home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Views / Sources / UTEView.cp < prev   
Encoding:
Text File  |  1996-04-04  |  89.3 KB  |  3,217 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UTEView.cp
  3. // Copyright © 1984-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UTEVIEW__
  7. #include "UTEView.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. //    #ifndef __UAPPLICATION__
  13. //    #include "UApplication.h"
  14. //    #endif
  15.  
  16. #ifndef __UCLIPBOARDMGR__
  17. #include "UClipboardMgr.h"
  18. #endif
  19.  
  20. #ifndef __UDEBUG__
  21. #include "UDebug.h"
  22. #endif
  23.  
  24. #ifndef __UDISPATCHER__
  25. #include "UDispatcher.h"
  26. #endif
  27.  
  28. #ifndef __UDOCUMENT__
  29. #include "UDocument.h"
  30. #endif
  31.  
  32. #if qDrag
  33. #ifndef __UDRAGDROP__
  34. #include "UDragDrop.h"
  35. #endif
  36.  
  37. #endif
  38.  
  39. #ifndef __UDRAGDROPBEHAVIOR__
  40. #include "UDragDropBehavior.h"
  41. #endif
  42.  
  43. #ifndef __UERRORMGR__
  44. #include "UErrorMgr.h"
  45. #endif
  46.  
  47. #ifndef __UFAILURE__
  48. #include "UFailure.h"
  49. #endif
  50.  
  51. #ifndef __UFILE__
  52. #include "UFile.h"
  53. #endif
  54.  
  55. #ifndef __UGEOMETRY__
  56. #include "UGeometry.h"
  57. #endif
  58.  
  59. #ifndef __ULIST__
  60. #include "UList.h"
  61. #endif
  62.  
  63. #ifndef __UMACAPPGLOBALS__
  64. #include "UMacAppGlobals.h"
  65. #endif
  66.  
  67. #ifndef __UMACAPPUTILITIES__
  68. #include "UMacAppUtilities.h"
  69. #endif
  70.  
  71. #ifndef __UMEMORY__
  72. #include "UMemory.h"
  73. #endif
  74.  
  75. #ifndef __UMENUMGR__
  76. #include "UMenuMgr.h"
  77. #endif
  78.  
  79. #ifndef __UPATCH__
  80. #include "UPatch.h"
  81. #endif
  82.  
  83. #ifndef __UPRINTHANDLER__
  84. #include "UPrintHandler.h"
  85. #endif
  86.  
  87. #ifndef __USCROLLER__
  88. #include "UScroller.h"
  89. #endif
  90.  
  91. #ifndef __USTREAM__
  92. #include "UStream.h"
  93. #endif
  94.  
  95. #ifndef __UTECOMMANDS__
  96. #include "UTECommands.h"
  97. #endif
  98.  
  99. #ifndef __UWINDOW__
  100. #include "UWindow.h"
  101. #endif
  102.  
  103. // Toolbox
  104.  
  105. #ifndef __ALIASES__
  106. #include <Aliases.h>
  107. #endif
  108.  
  109. #ifndef __DIALOGS__
  110. #include <Dialogs.h>
  111. #endif
  112.  
  113. #ifndef __EDITIONS__
  114. #include <Editions.h>
  115. #endif
  116.  
  117. #ifndef __ERRORS__
  118. #include <Errors.h>
  119. #endif
  120.  
  121. #ifndef __FONTS__
  122. #include <Fonts.h>
  123. #endif
  124.  
  125. #ifndef __GESTALT__
  126. #include <Gestalt.h>
  127. #endif
  128.  
  129. #ifndef __LOWMEM__
  130. #include <LowMem.h>
  131. #endif
  132.  
  133. #ifndef __MENUS__
  134. #include <Menus.h>
  135. #endif
  136.  
  137. #ifndef __PACKAGES__
  138. #include <Packages.h>
  139. #endif
  140.  
  141. #ifndef __SCRAP__
  142. #include <Scrap.h>
  143. #endif
  144.  
  145. #ifndef __SCRIPT__
  146. #include <Script.h>
  147. #endif
  148.  
  149. #ifndef __TOOLUTILS__
  150. #include <ToolUtils.h>
  151. #endif
  152.  
  153. // ANSI
  154.  
  155. #ifndef __LIMITS__
  156. #include <limits.h>
  157. #endif
  158.  
  159. #ifndef __STDIO__
  160. #include <stdio.h>
  161. #endif
  162.  
  163.  
  164. //========================================================================================
  165. // static data members
  166. //========================================================================================
  167.  
  168. TEClickLoopUPP TTEView::fgDefClickLoopProc;        //  Standard TextEdit click loop routine
  169. TTEView* TTEView::fgCurrTEView;
  170. TEClickLoopUPP TTEView::fgClickLoopProc;
  171. #if qDebug
  172. Boolean TTEView::fgTEIntenseDebugging;            // (has external) For the benefit of ClickLoopForTTEView only
  173. #endif
  174.  
  175. //----------------------------------------------------------------------------------------
  176. // InitUTEView: 
  177. //----------------------------------------------------------------------------------------
  178. #pragma segment TEInit
  179.  
  180. void InitUTEView()
  181. {
  182.     if (!gUTEViewInitialized)
  183.     {
  184.         gUTEViewInitialized = TRUE;
  185. #if qTemplateViews
  186.         {
  187.             // So we can create TTEView objects from view resources
  188.             MA_REGISTER_SIGNATURE(TTEView, kStdTEView);
  189.         }
  190. #endif
  191.  
  192.         if (!TTEView::fgClickLoopProc)
  193.             FailNIL(TTEView::fgClickLoopProc = NewTEClickLoopProc(TTEView::ClickLoopForTTEView));
  194.     }
  195. }
  196.  
  197. //========================================================================================
  198. // CLASS TTEView
  199. //========================================================================================
  200. #undef Inherited
  201. #define Inherited TView
  202.  
  203. #pragma segment TEOpen
  204. MA_DEFINE_CLASS_M1(TTEView,
  205.                    Inherited);
  206.  
  207. //----------------------------------------------------------------------------------------
  208. // TTEView constructor
  209. //----------------------------------------------------------------------------------------
  210. #pragma segment TEOpen
  211.  
  212. TTEView::TTEView()
  213. {
  214.     fWantsToBeTarget = TRUE;
  215.     fCursorID = iBeamCursor;
  216.  
  217.     fTextStyle = gSystemStyle;
  218.     fInset = gZeroVRect;
  219.     fTypingCommand = NULL;
  220.     fHTE = NULL;
  221.     fText = NULL;
  222.     fSavedTEHandle = NULL;
  223.     fLastHeight = 0;
  224.     fLastWidth = 0;
  225.     fMinAhead = kMinAhead;
  226.     fLastPageBreak = 0;
  227.     fKeyCommandNumber = cTyping;
  228.     // fControlChars = [chLeft, chRight, chUp, chDown, chBackspace, chReturn];
  229.     fControlChars = macroAsSetElem(chLeft) | macroAsSetElem(chRight) | macroAsSetElem(chUp) | macroAsSetElem(chDown) | macroAsSetElem(chBackspace) | macroAsSetElem(chReturn);
  230.     fMaxChars = kUnlimited;
  231.     fTextStyleRsrcID = kNoResource;
  232.     fJustification = teFlushDefault;
  233.     fLastLine = 0;
  234.     fSelAnchor = 0;
  235.     fUpDownH = 0;
  236.     fPreferOutline = kDontPreferOutline;
  237.     fAcceptsChanges = TRUE;                        // Stuff to false if you don't want to
  238.     // allow Cut, Paste, or Typing
  239.     fStyleType = kWithStyle;
  240.     fAutoWrap = TRUE;
  241.     fFreeText = TRUE;
  242.     fSpecsChanged = FALSE;
  243.     fUpDown = FALSE;
  244. #if qDrag
  245.     fHiliteRgn = NULL;
  246.     fLastCaretTime = 0L;
  247.     fLastCaretOffset = 0;
  248.     fCaretIsShown = FALSE;
  249. #endif // qDrag
  250.  
  251. }
  252.  
  253. //----------------------------------------------------------------------------------------
  254. // TTEView::ITEView: 
  255. //----------------------------------------------------------------------------------------
  256. #pragma segment TEOpen
  257.  
  258. void TTEView::ITEView(TDocument* itsDocument,
  259.                       TView* itsSuperView,
  260.                       const VPoint& itsLocation,
  261.                       const VPoint& itsSize,
  262.                       SizeDeterminer itsHDeterminer,
  263.                       SizeDeterminer itsVDeterminer,
  264.                       const VRect& itsInset,
  265.                       const TextStyle& itsTextStyle,
  266.                       short itsJustification,
  267.                       Boolean itsStyleType,
  268.                       Boolean itsAutoWrap)
  269.  
  270. {
  271.     IView(itsDocument, itsSuperView, itsLocation, itsSize, itsHDeterminer, itsVDeterminer);
  272.  
  273. #if qDebug
  274.     if (!gUTEViewInitialized)
  275.     {
  276.         ProgramBreak("InitUTEView must be called before creating a TE View.");
  277.         Failure(noErr, 0);
  278.     }
  279. #endif
  280.  
  281.     fInset = itsInset;
  282.     fTextStyle = itsTextStyle;
  283.     fJustification = itsJustification;
  284.     fStyleType = itsStyleType;
  285.     fAutoWrap = itsAutoWrap;
  286.  
  287.     FailInfo fi;
  288.     Try(fi)
  289.     {
  290.         MakeTERecord();
  291.  
  292.         fSelAnchor = (*fHTE)->selStart;
  293.         TESetClickLoop(fgClickLoopProc, fHTE);
  294.         fText = (*fHTE)->hText;
  295.  
  296.         SetIdleFreq(0);                            // Idle ASAP 
  297.  
  298.         TEFeatureFlag(teFOutlineHilite, teBitSet, fHTE);
  299.  
  300.         AddAdorner(gSelectionAdorner, kDrawView, FALSE);// Wants DoHighlightSelection called
  301.         fi.Success();
  302.     }
  303.     else                                        // Recover
  304.     {
  305.         Free();
  306.         fi.ReSignal();
  307.     }
  308. }
  309.  
  310. //----------------------------------------------------------------------------------------
  311. // TTEView::Clone: 
  312. //----------------------------------------------------------------------------------------
  313. #pragma segment TENonRes
  314.  
  315. TObject* TTEView::Clone()                        // override 
  316. {
  317.     MAVolatileInit(TEStyleHandle, theStyles, NULL);
  318.     MAVolatileInit(STHandle, theElements, NULL);
  319.     MAVolatileInit(LHHandle, theLineHeights, NULL);
  320.     MAVolatileInit(NullStHandle, theNullStyles, NULL);
  321.     MAVolatileInit(Handle, theText, NULL);
  322.  
  323.     MAVolatileInit(TTEView * , aClonedTTEView, (TTEView *)(Inherited::Clone()));
  324.     MAVolatileInit(SignedByte, wasState, 0);
  325.  
  326.     aClonedTTEView->fHTE = NULL;
  327.     aClonedTTEView->fSavedTEHandle = NULL;
  328.     aClonedTTEView->fText = NULL;
  329.     aClonedTTEView->fTypingCommand = NULL;
  330.  
  331.     FailInfo fi;
  332.     Try(fi)
  333.     {
  334.         NullStHandle oldNullStyles = NULL;
  335.         StScrpHandle oldNullScrap = NULL;
  336.         LHHandle oldLineHeights = NULL;
  337.         STHandle oldElements = NULL;
  338.         TEStyleHandle oldStyles = NULL;
  339.         STHandle inputElements = NULL;
  340.  
  341.         if (fHTE)
  342.         {
  343.             GrafPtr oldPort;
  344.             TextStyle aTextStyle;
  345.  
  346.             CWhileOutlinePreferred setOP(fPreferOutline);
  347.  
  348.             GetPort(&oldPort);
  349.             SetPortWindowPort(gWorkPort);
  350.             aTextStyle = fTextStyle;
  351.             SetPortTextStyle(aTextStyle);
  352.  
  353.             wasState = LockHandle((Handle)(fHTE));
  354.             {
  355.                 CRect destRect((*fHTE)->destRect);
  356.                 CRect viewRect((*fHTE)->viewRect);
  357.                 if (fStyleType == kWithStyle)
  358.                     aClonedTTEView->fHTE = TEStyleNew(&destRect, &viewRect);
  359.                 else
  360.                     aClonedTTEView->fHTE = TENew(&destRect, &viewRect);
  361.             }
  362.  
  363.             SetPort(oldPort);
  364.  
  365.             FailNIL(aClonedTTEView->fHTE);
  366.  
  367.             // Copy some fields from the original TERecord into the cloned TERecord
  368.             (*(aClonedTTEView->fHTE))->just = (*fHTE)->just;
  369.             (*(aClonedTTEView->fHTE))->crOnly = (*fHTE)->crOnly;
  370.             TESetWordBreak((*fHTE)->wordBreak, aClonedTTEView->fHTE);
  371.             TESetClickLoop((*fHTE)->clickLoop, aClonedTTEView->fHTE);
  372.  
  373.             // These internal fields need to be cloned too
  374.             (*(aClonedTTEView->fHTE))->selRect = (*fHTE)->selRect;
  375.             (*(aClonedTTEView->fHTE))->selPoint = (*fHTE)->selPoint;
  376.  
  377.             // Clone the styles record since clone or stuffstyles doesn't do it for us 
  378.             if (fStyleType == kWithStyle)
  379.             {
  380.                 TEStyleHandle inputStyles;
  381.  
  382.                 ExtractStyles(inputStyles, inputElements);
  383.                 oldStyles = TEGetStyleHandle(aClonedTTEView->fHTE);
  384.  
  385.                 // Remember pointers to the memory blocks allocated by TEStyleNew
  386.                 oldElements = (*oldStyles)->styleTab;
  387.                 oldLineHeights = (*oldStyles)->lhTab;
  388.                 oldNullStyles = (*oldStyles)->nullStyle;
  389.  
  390.                 if (oldNullStyles)
  391.                     oldNullScrap = (*oldNullStyles)->nullScrap;
  392.                 else
  393.                     oldNullScrap = NULL;
  394.  
  395.                 theStyles = inputStyles;
  396.                 PermHandToHand((Handle &)theStyles);
  397.  
  398.                 theElements = inputElements;
  399.                 PermHandToHand((Handle &)theElements);
  400.  
  401.                 theLineHeights = (*inputStyles)->lhTab;
  402.                 PermHandToHand((Handle &)theLineHeights);
  403.  
  404.                 theNullStyles = (*inputStyles)->nullStyle;
  405.                 if (theNullStyles)
  406.                 {
  407.                     PermHandToHand((Handle &)theNullStyles);
  408.                     if (oldNullScrap)
  409.                     {
  410.                         StScrpHandle theNullScrap = oldNullScrap;
  411.                         PermHandToHand((Handle &)theNullScrap);
  412.                         (*theNullStyles)->nullScrap = theNullScrap;
  413.                     }
  414.                 }
  415.  
  416.                 (*theStyles)->nullStyle = theNullStyles;// Replace NULL style handle 
  417.                 (*theStyles)->lhTab = theLineHeights;// Replace line heights table handle 
  418.                 (*theStyles)->styleTab = theElements;// Replace STElements handle 
  419.  
  420.                 (*theStyles)->teRefCon = (*oldStyles)->teRefCon;// clone the refCon
  421.  
  422.                 // Now that the cloned elements have been added to the
  423.                 // TE Record, delete the old versions (allocated by
  424.                 // TEStyleNew) and clear out the local variables that
  425.                 // point to the cloned items, so that they failure
  426.                 // handler will not try to free the same item twice.
  427.                 theElements = NULL;
  428.                 theLineHeights = NULL;
  429.                 theNullStyles = NULL;
  430.                 oldElements = (STHandle)(DisposeIfHandle((Handle)oldElements));
  431.                 oldLineHeights = (LHHandle)(DisposeIfHandle((Handle)oldLineHeights));
  432.                 oldNullStyles = (NullStHandle)(DisposeIfHandle((Handle)oldNullStyles));
  433.                 oldNullScrap = (StScrpHandle)(DisposeIfHandle((Handle)oldNullScrap));
  434.  
  435.                 // NOTE!! TESetStyleHandle will dispose of oldStyles for us, but
  436.                 // not any of the handles contained INSIDE of oldStyles (argh!)
  437.                 // TextEdit is an Evil Dog.
  438.                 TESetStyleHandle(theStyles, aClonedTTEView->fHTE);
  439.                 theStyles = NULL;
  440.             }
  441.  
  442.             aClonedTTEView->fSavedTEHandle = (*aClonedTTEView->fHTE)->hText;// Save existing handle 
  443.             theText = fText;
  444.             PermHandToHand((Handle &)theText);
  445.             (*aClonedTTEView->fHTE)->hText = theText;// Install new handle 
  446.             aClonedTTEView->fText = theText;    // Make a local copy, too 
  447.             theText = NULL;
  448.  
  449.             // Don't forget to update the length field of the new TE Record
  450.             (*aClonedTTEView->fHTE)->teLength = (*fHTE)->teLength;
  451.  
  452.             // Copy the insertion point of the old TE record
  453.             aClonedTTEView->SetSelection((*fHTE)->selStart, (*fHTE)->selEnd, kDontRedraw);
  454.  
  455.             HSetState((Handle)(fHTE), wasState);
  456.         }
  457.         fi.Success();
  458.     }
  459.     else                                        // Recover
  460.     {
  461.         // Usually, aClonedTTEView->Free will delete these
  462.         // elements for us, but we still have to worry about the
  463.         // case where PermHandToHand fails before the structures
  464.         // we are cloning are assigned to the TE Record.  This
  465.         // is why these local variables are set to NULL as soon
  466.         // as they are added to the TE Record.
  467.         theElements = (STHandle)(DisposeIfHandle((Handle)theElements));
  468.         theLineHeights = (LHHandle)(DisposeIfHandle((Handle)theLineHeights));
  469.         theNullStyles = (NullStHandle)(DisposeIfHandle((Handle)theNullStyles));
  470.         theText = DisposeIfHandle(theText);
  471.         theStyles = (TEStyleHandle)(DisposeIfHandle((Handle)theStyles));
  472.  
  473.         aClonedTTEView->Free();
  474.  
  475.         // We shouldn't leave this handle locked if we fail to clone it
  476.         if (fHTE)
  477.             HUnlock((Handle)(fHTE));
  478.  
  479.         fi.ReSignal();
  480.     }
  481.  
  482.     aClonedTTEView->RecalcText();
  483.  
  484.     return aClonedTTEView;
  485. }
  486.  
  487. //----------------------------------------------------------------------------------------
  488. // TTEView::Free: 
  489. //----------------------------------------------------------------------------------------
  490. #pragma segment TEClose
  491.  
  492. TTEView::~TTEView()
  493. {
  494.     if (fgCurrTEView == this)
  495.         fgCurrTEView = NULL;
  496.  
  497.     if (fHTE)
  498.     {
  499.         if (fSavedTEHandle)
  500.         {
  501.             // Worry about fText separately. Put back the handle which TE allocated.
  502.             (*fHTE)->hText = fSavedTEHandle;
  503.  
  504.             // This is here because it only makes sense if fSavedTEHandle is not NULL.
  505.             (*fHTE)->teLength = (short)GetHandleSize((*fHTE)->hText);//!!! Note Size->short cast
  506.  
  507.             if (fFreeText)
  508.                 fText = DisposeIfHandle(fText);
  509.             else
  510.                 fText = NULL;                    // Always drop my reference 
  511.         }
  512.         TEDispose(fHTE);
  513.         fHTE = NULL;
  514.  
  515.         fSavedTEHandle = NULL;
  516.     }
  517. }
  518.  
  519. //----------------------------------------------------------------------------------------
  520. // TTEView::GetStandardSignature: 
  521. //----------------------------------------------------------------------------------------
  522. #pragma segment TEWriteResource
  523.  
  524. IDType TTEView::GetStandardSignature()            // override 
  525. {
  526.     return kStdTEView;
  527. }
  528.  
  529. //----------------------------------------------------------------------------------------
  530. // TTEView::ReadFields: 
  531. //----------------------------------------------------------------------------------------
  532. #pragma segment TEReadResource
  533.  
  534. void TTEView::ReadFields(TStream* aStream)        // override 
  535. {
  536.     VRect vr;
  537.  
  538.     Inherited::ReadFields(aStream);
  539.  
  540. #if qDebug
  541.     if (!gUTEViewInitialized)
  542.     {
  543.         ProgramBreak("InitUTEView must be called before creating a TE View.");
  544.         Failure(noErr, 0);
  545.     }
  546. #endif
  547.  
  548.     FailInfo fi;
  549.     Try(fi)
  550.     {
  551.         fStyleType = aStream->ReadBoolean();
  552.         fAutoWrap = aStream->ReadBoolean();
  553.         fAcceptsChanges = aStream->ReadBoolean();
  554.         fFreeText = aStream->ReadBoolean();
  555.         fKeyCommandNumber = aStream->ReadLong();
  556.         fMaxChars = aStream->ReadInteger();
  557.         aStream->ReadVRect(vr);
  558.         fInset = vr;
  559.         fJustification = aStream->ReadInteger();
  560.         fTextStyleRsrcID = aStream->ReadInteger();
  561.         if (fTextStyleRsrcID != kNoResource)
  562.         {
  563.             TextStyle itsTextStyle;
  564.             MAGetTextStyle(fTextStyleRsrcID, itsTextStyle);
  565.             fTextStyle = itsTextStyle;
  566.         }
  567.  
  568.         fPreferOutline = aStream->ReadBoolean();
  569.  
  570.         MakeTERecord();
  571.         fi.Success();
  572.     }
  573.     else                                        // Recover
  574.     {
  575.         Free();
  576.         fi.ReSignal();
  577.     }
  578.  
  579.     fSelAnchor = (*fHTE)->selStart;
  580.     TESetClickLoop(fgClickLoopProc, fHTE);
  581.     fText = (*fHTE)->hText;
  582.  
  583.     TEFeatureFlag(teFOutlineHilite, teBitSet, fHTE);
  584. }
  585.  
  586. //----------------------------------------------------------------------------------------
  587. // TTEView::WriteFields: 
  588. //----------------------------------------------------------------------------------------
  589. #pragma segment TEWriteResource
  590.  
  591. void TTEView::WriteFields(TStream* aStream)        // override 
  592. {
  593.     Inherited::WriteFields(aStream);
  594.  
  595.     aStream->WriteBoolean(fStyleType);
  596.     aStream->WriteBoolean(fAutoWrap);
  597.     aStream->WriteBoolean(fAcceptsChanges);
  598.     aStream->WriteBoolean(fFreeText);
  599.     aStream->WriteLong(fKeyCommandNumber);
  600.     aStream->WriteInteger(fMaxChars);
  601.     aStream->WriteVRect(fInset);
  602.     aStream->WriteInteger(fJustification);
  603.     aStream->WriteInteger(fTextStyleRsrcID);
  604.     aStream->WriteBoolean(fPreferOutline);
  605. }
  606.  
  607. //----------------------------------------------------------------------------------------
  608. // TTEView::BecameWindowTarget: 
  609. //----------------------------------------------------------------------------------------
  610. #pragma segment TERes
  611.  
  612. void TTEView::BecameWindowTarget()                // Override 
  613. {
  614.     DoHighlightSelection(fActiveHL, hlOn);
  615.     fActiveHL = hlOn;
  616.  
  617.     Inherited::BecameWindowTarget();
  618. }
  619.  
  620. //----------------------------------------------------------------------------------------
  621. // TTEView::BecameTarget: 
  622. //----------------------------------------------------------------------------------------
  623. #pragma segment TERes
  624.  
  625. void TTEView::BecameTarget()                    // Override 
  626. {
  627.     SetActive(TRUE);
  628.  
  629.     Inherited::BecameTarget();
  630. }
  631.  
  632. //----------------------------------------------------------------------------------------
  633. // TTEView::ClickLoop: 
  634. //----------------------------------------------------------------------------------------
  635. #pragma segment TENonRes
  636.  
  637. Boolean TTEView::ClickLoop()
  638. {
  639.     if (StillDown())
  640.     {
  641.         TScroller * scroller = GetScroller(kAnySuperView);
  642.         if (scroller && scroller->Focus())
  643.         {
  644.             CPoint msePt;
  645.             GetMouse(msePt);
  646.  
  647.             VPoint delta;
  648.             scroller->AutoScroll(scroller->QDToViewPt(msePt), delta);// find how much should scroll 
  649.             if (Focus())
  650.             {
  651.                 CRect visRect(GetVisibleQDRect());
  652.                 for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  653.                 {
  654.                     short lead = (short)(-visRect[topLeft][vhs]);//!!! long->short cast
  655.                     short trail = (short)(fSize[vhs] - visRect[botRight][vhs]);//!!! long->short cast
  656.  
  657.                     if (delta[vhs] < 0)
  658.                         delta[vhs] = MinMax(lead, delta[vhs], 0);
  659.                     else
  660.                         delta[vhs] = MinMax(0, delta[vhs], trail);
  661.                 }
  662.                 // The intent of the above is not to do autoscrolling that would scroll
  663.                 // beyond the subview boundary in any direction
  664.  
  665.                 if (delta != gZeroVPt)
  666.                 {
  667.                     scroller->ScrollBy(delta, kRedraw);
  668.                     Update();                    // make sure the scrolling was visible 
  669.                 }
  670.             }
  671.         }
  672.  
  673.         // Focus may have changed, which could change lots of things, thus requiring us,
  674.         // tiresomely, to take some or all of the following restorative precautions b/ c
  675.         // clickloop expects us to be clipped to the destrect.
  676.         if (Focus())
  677.         {
  678.             CTemporaryRegion rRgn;
  679.             RectRgn(rRgn, &CRect((*fHTE)->destRect));
  680.             ClipFurtherTo(rRgn, gZeroPt);
  681.         }
  682.     }
  683.  
  684.     return TRUE;                                // Still consider the mouse to be down 
  685. }
  686.  
  687. //----------------------------------------------------------------------------------------
  688. // TTEView::AutoScrolling: 
  689. //----------------------------------------------------------------------------------------
  690. #pragma segment TENonRes
  691.  
  692. void TTEView::AutoScrolling(Boolean doScrolling)
  693. {
  694.     if (fHTE)
  695.         TEAutoView(doScrolling, fHTE);
  696. }
  697.  
  698. //----------------------------------------------------------------------------------------
  699. // TTEView::BeInPort: 
  700. //----------------------------------------------------------------------------------------
  701. #pragma segment TENonRes
  702.  
  703. void TTEView::BeInPort(GrafPtr itsPort)            // override 
  704. {
  705.     if (fHTE)
  706.     {
  707.         if (itsPort)
  708.             (*fHTE)->inPort = itsPort;
  709.         else
  710.         {
  711.             (*fHTE)->inPort = (GrafPtr)GetWindowPort(gWorkPort);
  712.             DoneTyping();
  713.             fSpecsChanged = TRUE;
  714.         }
  715.     }
  716.  
  717.     Inherited::BeInPort(itsPort);
  718. }
  719.  
  720. //----------------------------------------------------------------------------------------
  721. // TTEView::BeInScroller: 
  722. //----------------------------------------------------------------------------------------
  723. #pragma segment TENonRes
  724.  
  725. void TTEView::BeInScroller(TScroller* itsScroller)// override 
  726. {
  727.     if (fHTE && itsScroller)
  728.     {
  729.         short vertScrollUnit;
  730.  
  731.         if ((*fHTE)->lineHeight > 0)            // This works for both old && new TextEdit 
  732.             vertScrollUnit = (*fHTE)->lineHeight;
  733.         else
  734.             vertScrollUnit = GetDefFontSize();    // Ask for system default size 
  735.  
  736.         itsScroller->SetScrollParameters(VPoint(kStdScrollUnit, vertScrollUnit), FALSE, TRUE);
  737.     }
  738.  
  739.     Inherited::BeInScroller(itsScroller);
  740. }
  741.  
  742. //----------------------------------------------------------------------------------------
  743. // TTEView::CalcMinFrame: 
  744. //----------------------------------------------------------------------------------------
  745. #pragma segment TENonRes
  746.  
  747. VRect TTEView::CalcMinFrame()        // override 
  748. {
  749.     // Note that we omit the margins here, so that if TView::ComputeFrame rounds up to a
  750.     // page multiple, the margins will get tacked on after. 
  751.     VPoint minSize = VPoint(fSize.h - fInset.left - fInset.right, CalcRealHeight());
  752.  
  753.     if ((fSizeDeterminer[hSel] == sizeVariable) && (!fStyleType && !fAutoWrap))
  754.         minSize = VPoint(fLastWidth, minSize.v);
  755.  
  756.     VRect minFrame(Inherited::CalcMinFrame());
  757.     minFrame[botRight] = minFrame[topLeft] + minSize;
  758.     
  759.     return minFrame;
  760. }
  761.  
  762. //----------------------------------------------------------------------------------------
  763. // TTEView::CalcRealHeight: 
  764. //----------------------------------------------------------------------------------------
  765. #pragma segment TERes
  766.  
  767. long TTEView::CalcRealHeight()
  768. {
  769.     long theHeight = 0;                            // default return value.
  770.     Boolean lastIsCR;
  771.     short nLines;
  772.     short lineHeight;
  773.  
  774.     CWhileOutlinePreferred setOP(fPreferOutline);
  775.  
  776.     {
  777.         TERec & theTERec = **fHTE;
  778.  
  779.         lastIsCR = (theTERec.teLength <= 0) || ((*(CharsHandle)(theTERec.hText))[theTERec.teLength - 1] == chReturn);
  780.         nLines = theTERec.nLines;
  781.         lineHeight = theTERec.lineHeight;
  782.     }
  783.  
  784.     if (fStyleType != kWithStyle)
  785.     {
  786.         if (lastIsCR)
  787.             ++nLines;
  788.         theHeight = nLines * lineHeight;
  789.     }
  790.     else
  791.     {
  792.         if (nLines > 0)
  793.             theHeight = TEGetHeight(SHRT_MAX, 0, fHTE);
  794.  
  795.         if (lastIsCR)                            // if lastIsCR, then add to result of TEGetHeight
  796.         {
  797.             short theMode = doAll;
  798.             TextStyle theStyle;
  799.             ContinuousStyle(SHRT_MAX, SHRT_MAX, theMode, theStyle);
  800.  
  801.             FontInfo theFontInfo;
  802.             short theFontHeight;
  803.             GetTextStyleFontInfo(theStyle, theFontInfo, theFontHeight);
  804.  
  805.             theHeight += theFontHeight;
  806.         }
  807.     }
  808.  
  809. #if qDebugMsg
  810.     if (gIntenseDebugging)
  811.         fprintf(stderr, "CalcRealHeight=%1d\n", theHeight);
  812. #endif
  813.  
  814.     return theHeight;
  815. }
  816.  
  817. //----------------------------------------------------------------------------------------
  818. // TTEView::CalcRealWidth: 
  819. //----------------------------------------------------------------------------------------
  820. #pragma segment TERes
  821.  
  822. long TTEView::CalcRealWidth()
  823. {
  824.     short fromChar;
  825.     short toChar;
  826.     short aWidth;
  827.     TextStyle theStyle;
  828.     SignedByte savedState;
  829.  
  830.  
  831.     aWidth = 0;
  832.  
  833.     if (!fStyleType)
  834.     {
  835.         if (Focus())
  836.         {
  837.             theStyle = fTextStyle;
  838.             SetPortTextStyle(theStyle);
  839.  
  840.             aWidth = 0;
  841.             fromChar = (*fHTE)->lineStarts[0];
  842.  
  843.             savedState = LockHandle((Handle)(*fHTE)->hText);
  844.  
  845.             for (short index = 1; index <= (*fHTE)->nLines; ++index)
  846.             {
  847.                 toChar = (*fHTE)->lineStarts[index] - 1;
  848.                 aWidth = (short)Max(aWidth, TextWidth(*((*fHTE)->hText), fromChar, (toChar - fromChar) + 1));//!!! long->short cast
  849.                 fromChar = toChar + 1;
  850.             }
  851.  
  852.             HSetState((Handle)(*fHTE)->hText, savedState);
  853.  
  854.             return aWidth;
  855.         }
  856.     }
  857.     else
  858.     {
  859. #if qDebug
  860.         ProgramBreak("IN TTEView.CalcRealWidth: called for a styled TE Record");
  861. #endif
  862.  
  863.     }
  864.     return aWidth;
  865. }
  866.  
  867. //----------------------------------------------------------------------------------------
  868. // TTEView::ChangeWrap: 
  869. //----------------------------------------------------------------------------------------
  870. #pragma segment TENonRes
  871.  
  872. void TTEView::ChangeWrap(Boolean newAutoWrap,
  873.                          Boolean redraw)
  874. {
  875.     fAutoWrap = newAutoWrap;
  876.     if (newAutoWrap)
  877.         (*fHTE)->crOnly = 0;
  878.     else
  879.         (*fHTE)->crOnly = -1;
  880.     if (redraw)
  881.     {
  882.         RecalcText();
  883.         SynchView(kRedraw);
  884.     }
  885. }
  886.  
  887. //----------------------------------------------------------------------------------------
  888. // TTEView::ComputeFrame: 
  889. //----------------------------------------------------------------------------------------
  890. #pragma segment TENonRes
  891.  
  892. void TTEView::ComputeFrame(VRect& newFrame)        // override
  893. {
  894.     Inherited::ComputeFrame(newFrame);
  895.  
  896.     for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  897.     {
  898.         switch (fSizeDeterminer[vhs])
  899.         {
  900.             case sizeFixed:
  901.             case sizeRelSuperView:
  902.                 break;
  903.  
  904.             case sizeSuperView:
  905.                 if (fSuperView != NULL)
  906.                     break;
  907.                 // else drop through to default
  908.             default:
  909.                 newFrame[botRight][vhs] += fInset[topLeft][vhs] + fInset[botRight][vhs];
  910.                 break;
  911.         }
  912.     }
  913.     // we must limit the frame to kMaxCoord, since Text Edit doesn't allow height to exceed 32K
  914.     newFrame.bottom = newFrame.top + Min(kMaxCoord, newFrame.bottom - newFrame.top);
  915. }
  916.  
  917. //----------------------------------------------------------------------------------------
  918. // TTEView::CalcSelLoc: 
  919. //----------------------------------------------------------------------------------------
  920. #pragma segment TERes
  921.  
  922. void TTEView::CalcSelLoc(VRect& selectionRect)
  923. {
  924.     CharsHandle handleToText;
  925.     short startOfSelection;
  926.     short endOfSelection;
  927.     short charCount;
  928.     short lineHeight;
  929.     short fontAscent;
  930.     TextStyle theStyle;
  931.     Boolean selectionIsTheLastReturn;
  932.     short theMode;
  933.     FontInfo theFontInfo;
  934.     short theFontHeight;
  935.  
  936.     CWhileOutlinePreferred setOP(fPreferOutline);
  937.  
  938.     {
  939.         TERec & theTERec = **fHTE;
  940.  
  941.         charCount = theTERec.teLength;
  942.         startOfSelection = theTERec.selStart;
  943.         endOfSelection = theTERec.selEnd;
  944.         handleToText = (CharsHandle)(theTERec.hText);
  945.  
  946.         if ((theTERec.selEnd - theTERec.selStart == 0) && (fIdleFreq == kMaxIdleTime))
  947.             SetIdleFreq(0);                        // Idle ASAP 
  948.     }
  949.  
  950.     selectionIsTheLastReturn = (startOfSelection == charCount) && (charCount > 0) && ((*handleToText)[charCount - 1] == chReturn);
  951.  
  952.     TEGetStyle(startOfSelection, &theStyle, &lineHeight, &fontAscent, fHTE);
  953.  
  954.     CPoint thePoint(TEGetPoint(startOfSelection, fHTE));
  955.     thePoint.v -= lineHeight;
  956.     selectionRect[topLeft] = QDToViewPt(thePoint);
  957.     selectionRect[botRight] = QDToViewPt(TEGetPoint(endOfSelection, fHTE));
  958.  
  959.     // Through System 6.0.4 TE TEGetPoint returns
  960.     // bogus numbers when the character count is 0.
  961.     if (charCount <= 0)
  962.     {
  963.         selectionRect.top = 0;
  964.         selectionRect.bottom = lineHeight;
  965.     }
  966.  
  967.     if (selectionIsTheLastReturn)
  968.     {
  969.         theMode = doAll;
  970.  
  971.         // Get the style so we know how tall to make the selection when its just the last return 
  972.         ContinuousStyle(SHRT_MAX, SHRT_MAX, theMode, theStyle);
  973.  
  974.         GetTextStyleFontInfo(theStyle, theFontInfo, theFontHeight);
  975.  
  976.         selectionRect.top = selectionRect.bottom;
  977.         selectionRect.bottom += theFontHeight;
  978.     }
  979.     else
  980.     {
  981.         // Correct errors by CalcSelLoc. If there is no selection then the "selection"
  982.         // consists of the bits enclosed by the insertion bar.
  983.         if (((*fHTE)->selEnd - (*fHTE)->selStart) == 0)
  984.             selectionRect.left = selectionRect.right - 1;
  985.  
  986.     }
  987. }
  988.  
  989. //----------------------------------------------------------------------------------------
  990. // TTEView::ContinuousStyle: 
  991. //----------------------------------------------------------------------------------------
  992. #pragma segment TERes
  993.  
  994. Boolean TTEView::ContinuousStyle(short firstChar,
  995.                                  short lastChar,
  996.                                  short& mode,
  997.                                  TextStyle& aStyle)
  998. {
  999.     short oldSelStart;
  1000.     short oldSelEnd;
  1001.     Boolean result;
  1002.  
  1003.  
  1004.     oldSelStart = (*fHTE)->selStart;
  1005.     oldSelEnd = (*fHTE)->selEnd;
  1006.  
  1007.     SetSelect(firstChar, lastChar, fHTE);        // Use SetSelect so this is invisible 
  1008.     result = TEContinuousStyle(&mode, &aStyle, fHTE);
  1009.     SetSelect(oldSelStart, oldSelEnd, fHTE);    // & so fSpecsChanged isn't touched
  1010.     return result;
  1011. }
  1012.  
  1013. //----------------------------------------------------------------------------------------
  1014. // TTEView::ContainsClipType: 
  1015. //----------------------------------------------------------------------------------------
  1016. #pragma segment TERes
  1017.  
  1018. Boolean TTEView::ContainsClipType(ResType aType)// override 
  1019. {
  1020.     return (aType == 'TEXT');
  1021. }
  1022.  
  1023. //----------------------------------------------------------------------------------------
  1024. // TTEView::DoBreakFollowing: Put in resident segment since this gets called while typing 
  1025. //----------------------------------------------------------------------------------------
  1026. #pragma segment TERes
  1027.  
  1028. VCoordinate TTEView::DoBreakFollowing(VHSelect vhs,
  1029.                                       VCoordinate previousBreak,
  1030.                                       Boolean& automatic)// override 
  1031. {
  1032.     VHSelect orthoVhs;
  1033.     short possibleLoc;
  1034.     TEStyleHandle theStyles;
  1035.     LHHandle lhTab;
  1036.     short height;
  1037.     short lineHeight;
  1038.     short lineNo;
  1039.     TPrintHandler * itsPrintHandler;
  1040.     short countLines;
  1041.  
  1042.     orthoVhs = gOrthogonal[vhs];
  1043.     automatic = TRUE;
  1044.  
  1045.     if ((itsPrintHandler = GetPrintHandler()) != NULL)
  1046.         possibleLoc = (short)Min(kMaxCoord, previousBreak + itsPrintHandler->GetViewPerPage()[orthoVhs]);//!!! long->short
  1047.  
  1048.     // We want to get rid of the on-screen margin represented by fMargin when printing, so
  1049.     // adjust things so that the portion of the view occupied by the screen margin doesn't
  1050.     // get printed.
  1051.     if (previousBreak == 0)
  1052.         possibleLoc += (short)fInset[topLeft][orthoVhs];//!!! long->short
  1053.  
  1054.     if ((fStyleType == kWithStyle) && (vhs == hSel))
  1055.     {
  1056.         if (fLastPageBreak == previousBreak)
  1057.         {
  1058.             height = fLastPageBreak;
  1059.             lineNo = fLastLine;
  1060.         }
  1061.         else
  1062.         {
  1063.             height = (short)fInset[topLeft][orthoVhs];//!!! VCoordinate->short
  1064.             lineNo = 0;
  1065.         }
  1066.  
  1067.         theStyles = TEGetStyleHandle(fHTE);
  1068.         lhTab = (*theStyles)->lhTab;
  1069.  
  1070.         countLines = (*fHTE)->nLines;
  1071.         if ((*fHTE)->teLength > 0)
  1072.         {
  1073.             // we want to see if the last line is empty (only a return)
  1074.             // Can't just look at the last byte in hText, because it could be
  1075.             // a multi-byte character.
  1076.             short offsetOfLastLine = (*fHTE)->lineStarts[countLines - 1];
  1077.             char firstByteInLastLine = (*(*fHTE)->hText)[offsetOfLastLine];
  1078.             if (firstByteInLastLine == chReturn)
  1079.                 countLines++;
  1080.         }
  1081.  
  1082.         while (lineNo < countLines)
  1083.         {
  1084.             lineHeight = (*lhTab)[lineNo].lhHeight;
  1085.             if (height + lineHeight <= possibleLoc)
  1086.                 height += lineHeight;
  1087.             else
  1088.                 break;
  1089.             ++lineNo;
  1090.         }
  1091.         if (lineNo >= countLines)
  1092.             possibleLoc = (short)Max(possibleLoc, height);//!!! long->short
  1093.         else if (height > previousBreak)
  1094.         {
  1095.             possibleLoc = height;
  1096.             fLastPageBreak = possibleLoc;
  1097.             fLastLine = lineNo;
  1098.         }
  1099.         // else the current line height was bigger than this page--print what we can.
  1100.         // next break we'll recalculate from the start again.
  1101.         fLastPageBreak = possibleLoc;
  1102.         fLastLine = lineNo;
  1103.     }
  1104.  
  1105.     if ((possibleLoc + fInset[topLeft][orthoVhs]) >= fSize[orthoVhs])
  1106.         return fSize[orthoVhs];
  1107.     else
  1108.         return possibleLoc;
  1109. }
  1110.  
  1111. //----------------------------------------------------------------------------------------
  1112. // TTEView::DoCalcViewPerPage: 
  1113. //----------------------------------------------------------------------------------------
  1114. #pragma segment TENonRes
  1115.  
  1116. VPoint TTEView::DoCalcViewPerPage()// override 
  1117. {
  1118.     VPoint returnVal(Inherited::DoCalcViewPerPage());    // Get max amount allowed given margins 
  1119.  
  1120. #if qDebugMsg
  1121.     if (gDebugPrinting)
  1122.         fprintf(stderr, "TTEView: incoming generic viewPerPage: %s\n", (const char*)returnVal);
  1123. #endif
  1124.  
  1125.     // Adjust for integral # of lines per page (unless the view is too small)
  1126.     if ((fStyleType != kWithStyle) && fHTE && (*fHTE)->lineHeight > returnVal.v)
  1127.         returnVal.v = (*fHTE)->lineHeight * (returnVal.v / (*fHTE)->lineHeight);
  1128.  
  1129. #if qDebug
  1130.     if (gDebugPrinting)
  1131.         fprintf(stderr, "TTEView: computed viewPerPage: %s\n", (const char*)returnVal);
  1132. #endif
  1133.  
  1134.     return returnVal;
  1135. }
  1136.  
  1137. //----------------------------------------------------------------------------------------
  1138. // TTEView::DoIdle: 
  1139. //----------------------------------------------------------------------------------------
  1140. #pragma segment TERes
  1141.  
  1142. Boolean TTEView::DoIdle(IdlePhase phase)        // override 
  1143. {
  1144.     if (phase == idleContinue)
  1145.         if (fHTE && ((*fHTE)->selEnd - (*fHTE)->selStart == 0) && IsEnabled())
  1146.         {
  1147.             if (fAcceptsChanges && IsDrawable())
  1148.             {
  1149.                 CWhileOutlinePreferred setOP(fPreferOutline);
  1150.                 TEIdle(fHTE);
  1151.             }
  1152.             SetIdleFreq(Max(GetCaretTime() / 2, 1));// Reset idle frequency in case
  1153.             // user changed it
  1154.         }
  1155.         else
  1156.             SetIdleFreq(kMaxIdleTime);            // No need to bother anyone. 
  1157.     return FALSE;                                // Didn't free myself 
  1158. }
  1159.  
  1160. //----------------------------------------------------------------------------------------
  1161. // TTEView::DoKeyEvent: The Tab character has no width in some fonts, and so can cause
  1162. // confusing screen feedback. It is filtered out by default. If you want to include it in
  1163. // your text union it into fControlChars.
  1164. //----------------------------------------------------------------------------------------
  1165. #pragma segment TERes
  1166.  
  1167. void TTEView::DoKeyEvent(TToolboxEvent* event)    // override 
  1168. {
  1169.     TTETypingCommand * aTypingCommand = NULL;
  1170.     Boolean needNewCommand = FALSE;
  1171.     Boolean handledCharacter = FALSE;
  1172.     Boolean selecting = FALSE;
  1173.     short goToPos = (*fHTE)->selStart;
  1174.     short i = 0;
  1175.     short nonAnchor;
  1176.     short newStart;
  1177.     short newEnd;
  1178.     Boolean towardStart;
  1179.  
  1180.     CStr2 text(event->fText);
  1181.  
  1182.     if (IsEnabled())                            // if view is not enabled then we don't take ANY keystrokes
  1183.     {
  1184.         if (text >= chSpace || (text < chSpace && macroIn(fControlChars, macroAsSetElem(text[1]))))// Check that the character should be accepted
  1185.         {
  1186.             if (((text == chLeft) || (text == chRight) || (text == chUp) || (text == chDown)) && Focus())// check for pure movement keys 
  1187.             {
  1188.                 DoneTyping();                    // Like mousedown, further typing == new command 
  1189.                 fSpecsChanged = TRUE;
  1190.                 //################
  1191.                 if ((text != chUp) && (text != chDown))
  1192.                     fUpDown = FALSE;
  1193.  
  1194.                 if ((text == chLeft) || (text == chRight))
  1195.                 {
  1196.                     towardStart = (text == chLeft);
  1197.                     if (GetScriptVariable((short)GetScriptManagerVariable(smKeyScript), smScriptRight) != 0)//!!! long->short
  1198.                         towardStart = !towardStart;
  1199.                 }
  1200.                 else
  1201.                     towardStart = FALSE;
  1202.  
  1203.                 {
  1204.                     TERec & theTERec = **fHTE;
  1205.  
  1206.                     if (theTERec.selStart == theTERec.selEnd)
  1207.                         fSelAnchor = theTERec.selStart;
  1208.                     if (fSelAnchor < 0)
  1209.                         if ((text == chUp) || (towardStart))
  1210.                             fSelAnchor = theTERec.selEnd;
  1211.                         else
  1212.                             fSelAnchor = theTERec.selStart;
  1213.                     if (fSelAnchor == theTERec.selEnd)
  1214.                         nonAnchor = theTERec.selStart;
  1215.                     else
  1216.                         nonAnchor = theTERec.selEnd;
  1217.                 }
  1218.  
  1219.                 if ((text == chUp) && (OffsetToLine(nonAnchor) == 0))
  1220.                 {
  1221.                     //same as command-Up
  1222.                     selecting = event->IsShiftKeyPressed();
  1223.                     handledCharacter = TRUE;
  1224.                     goToPos = 0;
  1225.                     fUpDown = FALSE;
  1226.                 }
  1227.                 else if ((text == chDown) && (OffsetToLine(nonAnchor) == (*fHTE)->nLines))
  1228.                 {
  1229.                     //same as command-Down
  1230.                     selecting = event->IsShiftKeyPressed();
  1231.                     handledCharacter = TRUE;
  1232.                     goToPos = (*fHTE)->teLength;
  1233.                     fUpDown = FALSE;
  1234.                 }
  1235.  
  1236.                 if ((!handledCharacter) && (text >= chLeft) && (text <= chDown))
  1237.                 {
  1238.                     SignedByte wasState = LockHandle((Handle)fHTE);//??? SRF - why is this getting locked?
  1239.  
  1240.                     selecting = event->IsShiftKeyPressed();
  1241.                     handledCharacter = TRUE;
  1242.  
  1243.                     if (event->IsCommandKeyPressed())
  1244.                     {
  1245.                         if (text == chUp)
  1246.                             goToPos = 0;
  1247.                         else if (text == chDown)
  1248.                             goToPos = (*fHTE)->teLength;
  1249.                         else if (towardStart)
  1250.                             goToPos = OffsetToLineStart(nonAnchor);
  1251.                         else
  1252.                             goToPos = OffsetToLineEnd(nonAnchor);
  1253.                         fUpDown = FALSE;
  1254.                     }
  1255.                     else if ((text == chUp) || (text == chDown))
  1256.                     {
  1257.                         VPoint aVPoint;
  1258.  
  1259.                         if (!fUpDown)
  1260.                         {
  1261.                             fUpDown = TRUE;
  1262.                             aVPoint = OffsetToPt(nonAnchor);
  1263.                             fUpDownH = (short)aVPoint.h;//!!! VCoordinate->short
  1264.                         }
  1265.                         if ((*fHTE)->lineHeight < 0)//styled text
  1266.                         {
  1267.                             i = OffsetToLine(nonAnchor);
  1268.                             i = (short)TEGetHeight(((long)i), ((long)i), fHTE);//!!! long->short
  1269.                         }
  1270.                         else
  1271.                             i = (*fHTE)->lineHeight;
  1272.                         if (text == chUp)
  1273.                             i = -i;
  1274.                         aVPoint = OffsetToPt(nonAnchor);
  1275.                         aVPoint.v += i;
  1276.                         aVPoint.h = fUpDownH;
  1277.                         goToPos = PtToOffset(aVPoint);
  1278.                         i = OffsetToLine(nonAnchor);
  1279.                         if ((text == chUp) && (goToPos == (*fHTE)->lineStarts[i]))
  1280.                             --goToPos;
  1281.                         else if ((text == chDown) && (OffsetToLine(goToPos) == i + 2))
  1282.                             ++goToPos;
  1283.                     }
  1284.                     else if (event->IsOptionKeyPressed())
  1285.                     {
  1286.                         Boolean expanding;
  1287.  
  1288.                         if (selecting)
  1289.                             if (towardStart)
  1290.                                 expanding = (nonAnchor <= fSelAnchor);
  1291.                             else
  1292.                                 expanding = (nonAnchor >= fSelAnchor);
  1293.                         else
  1294.                             expanding = TRUE;
  1295.                         goToPos = nonAnchor;
  1296.                         if (!expanding)
  1297.                             if (towardStart)
  1298.                             {
  1299.                                 newEnd = goToPos;
  1300.                                 while ((goToPos > fSelAnchor) && ((!WordBounds(goToPos, newStart, newEnd)) || (newEnd + 1 >= nonAnchor)))
  1301.                                     goToPos = newStart - 1;
  1302.                                 if (goToPos <= fSelAnchor)
  1303.                                 {
  1304.                                     expanding = TRUE;
  1305.                                     goToPos = fSelAnchor;
  1306.                                 }
  1307.                                 else
  1308.                                     goToPos = newEnd + 1;
  1309.                             }
  1310.                             else                //!towardStart
  1311.                                 {
  1312.                                     newStart = goToPos;
  1313.                                     while ((goToPos < fSelAnchor) && ((!WordBounds(goToPos, newStart, newEnd)) || (newStart <= nonAnchor)))
  1314.                                         goToPos = newEnd + 1;
  1315.                                     if (goToPos >= fSelAnchor)
  1316.                                     {
  1317.                                         expanding = TRUE;
  1318.                                         goToPos = fSelAnchor;
  1319.                                     }
  1320.                                 }
  1321.                         if (expanding)
  1322.                             if (towardStart)
  1323.                             {
  1324.                                 i = goToPos;
  1325.                                 newStart = goToPos;
  1326.                                 while ((goToPos > 0) && ((!WordBounds(goToPos, newStart, newEnd)) || (newStart >= i)))
  1327.                                     --goToPos;
  1328.                                 goToPos = (short)Min(goToPos, newStart);//!!! long->short
  1329.                             }
  1330.                             else                //!towardStart
  1331.                                 {
  1332.                                     newEnd = goToPos;
  1333.                                     i = (*fHTE)->teLength - 1;
  1334.                                     while ((goToPos < i) && !WordBounds(goToPos + 1, newStart, newEnd))
  1335.                                         ++goToPos;
  1336.                                     goToPos = (short)Max(goToPos, newEnd) + 1;//!!! long->short
  1337.                                 }
  1338.                     }
  1339.                     else if (event->IsShiftKeyPressed() || ((*fHTE)->selStart == (*fHTE)->selEnd))
  1340.                     {
  1341.                         if (towardStart)
  1342.                             goToPos = GetPrevCharacterOffset(nonAnchor);
  1343.                         else
  1344.                             goToPos = GetNextCharacterOffset(nonAnchor);
  1345.                     }
  1346.                     else                        // selStart != selEnd && ((text == chLeft)
  1347.                         // || (text == chRight))
  1348.                         {
  1349.                             if (towardStart)
  1350.                                 goToPos = (*fHTE)->selStart;
  1351.                             else
  1352.                                 goToPos = (*fHTE)->selEnd;
  1353.                         }
  1354.  
  1355.                     HSetState((Handle)fHTE, wasState);
  1356.  
  1357.                 }
  1358.  
  1359.                 handledCharacter = TRUE;
  1360.                 if (selecting)
  1361.                     SetSelection((short)Min(goToPos, fSelAnchor), (short)Max(goToPos, fSelAnchor), kRedraw);//!!! long->short
  1362.                 else
  1363.                     SetSelection(goToPos, goToPos, kRedraw);
  1364.                 ScrollSelectionIntoView(kRedraw);
  1365.             }
  1366.             else if (fAcceptsChanges && Focus())
  1367.             {
  1368.                 // Check max size for text, and that we're not running out of memory 
  1369.                 if ((text != chBackspace) && (text != chFwdDelete) && ((*fHTE)->selStart == (*fHTE)->selEnd))
  1370.                     if (((fMaxChars - GetHandleSize(fText)) < 1) || MemSpaceIsLow())
  1371.                     {
  1372.                         StdAlert(phTooManyChars);
  1373.                         //                        exit(DoKeyEvent);             // Flush further keystrokes 
  1374.                         return;
  1375.                     }
  1376.  
  1377.                 // This key will change the horizontal position of the insertion point
  1378.                 fUpDown = FALSE;
  1379.  
  1380.                 // Pass the character to the typing command, creating a new one if necessary 
  1381.                 needNewCommand = (fTypingCommand == NULL);
  1382.                 if (!needNewCommand)
  1383.                     needNewCommand = fTypingCommand->fCompleted;
  1384.  
  1385.                 if (needNewCommand)
  1386.                 {
  1387.                     aTypingCommand = DoMakeTypingCommand(text);
  1388.                     fTypingCommand = aTypingCommand;
  1389.                     PostCommand(aTypingCommand);
  1390.                 }
  1391.                 else
  1392.                 {
  1393.                     short oldLength = (*fHTE)->teLength;
  1394.                     fTypingCommand->AddCharacter(text);
  1395.                     // Once you're typing (first character already processed) collecting
  1396.                     // subsequent characters really shouldn't affect the menus unless
  1397.                     // you're keeping a character count in them or something that depends
  1398.                     // on the aggregate of the characters you've typed. The TextStyle for
  1399.                     // the first character would certainly apply to subsequent characters.
  1400.                     // So, this is one ideal place to say that the event _DOES NOT_ affect
  1401.                     // the menus. If the menus are already invalid they will stay so, but
  1402.                     // if they are valid then there is no need to invalidate them in the
  1403.                     // character collection process. When the user terminates the addition
  1404.                     // of characters with another event, the menus will be setup from that
  1405.                     // event. If you really feel you must, then you can always override,
  1406.                     // call Inherited and then set event->fAffectMenus back to true.
  1407.                     // (Rhymes with rue)
  1408.                     event->fAffectsMenus = ((*fHTE)->teLength == 0 || oldLength == 0);
  1409.                 }
  1410.                 handledCharacter = TRUE;
  1411.             }
  1412.         }
  1413.         if (fIdleFreq == kMaxIdleTime)
  1414.             SetIdleFreq(0);                        // Idle ASAP, since someone may somehow set an
  1415.         // insertion point and want it to flash. (the
  1416.         // idle time will be reset to match the caret
  1417.         // time in doidle.)
  1418.     }
  1419.  
  1420.     if (!handledCharacter)
  1421.         Inherited::DoKeyEvent(event);
  1422. }
  1423.  
  1424. //----------------------------------------------------------------------------------------
  1425. // TTEView::SetSelection: 
  1426. //----------------------------------------------------------------------------------------
  1427. #pragma segment TERes
  1428.  
  1429. void TTEView::SetSelection(short newSelStart,
  1430.                            short newSelEnd,
  1431.                            Boolean redraw)
  1432. {
  1433.     if (redraw && Focus())
  1434.     {
  1435.         short oldSelStart = (*fHTE)->selStart;
  1436.         short oldSelEnd = (*fHTE)->selEnd;
  1437.  
  1438.         CWhileOutlinePreferred setOP(fPreferOutline);
  1439.         TESetSelect(Max(newSelStart, 0), Min(newSelEnd, (*fHTE)->teLength), fHTE);
  1440.  
  1441. #if qDrag
  1442.         if (GetDraggable())
  1443.             gDispatcher->InvalidateMouseRegions();
  1444. #endif
  1445.  
  1446.     }
  1447.     else
  1448.         SetSelect((short)Max(newSelStart, 0), (short)Min(newSelEnd, (*fHTE)->teLength), fHTE);//!!! long->short
  1449.  
  1450.     if (newSelStart == newSelEnd)
  1451.         fSelAnchor = newSelStart;
  1452.  
  1453.     fSpecsChanged = TRUE;
  1454. }
  1455.  
  1456. //----------------------------------------------------------------------------------------
  1457. // TTEView::DoMakeEditCommand: 
  1458. //----------------------------------------------------------------------------------------
  1459. #pragma segment TESelCommand
  1460.  
  1461. TTECommand* TTEView::DoMakeEditCommand(CommandNumber aCommandNumber)
  1462. {
  1463.     TTECommand * aTECommand = NULL;
  1464.  
  1465.     switch (aCommandNumber)
  1466.     {
  1467.         case cCut:
  1468.         case cCopy:
  1469.             aTECommand = new TTECutCopyCommand;
  1470.             ((TTECutCopyCommand *)aTECommand)->ITECutCopyCommand(this, aCommandNumber);
  1471.             break;
  1472.  
  1473.         case cPaste:
  1474.             aTECommand = new TTEPasteCommand;
  1475.             ((TTEPasteCommand *)aTECommand)->ITEPasteCommand(this);
  1476.             break;
  1477.  
  1478.         case cClear:
  1479.             aTECommand = new TTECommand;
  1480.             aTECommand->ITECommand(this, aCommandNumber, TRUE);
  1481.             break;
  1482.  
  1483.     }
  1484.  
  1485.     return aTECommand;
  1486. }
  1487.  
  1488. //----------------------------------------------------------------------------------------
  1489. // TTEView::DoMakeStyleCommand: 
  1490. //----------------------------------------------------------------------------------------
  1491. #pragma segment TERes
  1492.  
  1493. TTEStyleCommand* TTEView::DoMakeStyleCommand(const TextStyle& aStyle,
  1494.                                              CommandNumber itsCommandNumber,
  1495.                                              short itsMode)
  1496. {
  1497.     TTEStyleCommand * aTEStyleCommand = new TTEStyleCommand;
  1498.  
  1499.     aTEStyleCommand->ITEStyleCommand(this, aStyle, itsCommandNumber, itsMode);
  1500.     return aTEStyleCommand;
  1501. }
  1502.  
  1503. //----------------------------------------------------------------------------------------
  1504. // TTEView::DoMakeTypingCommand: 
  1505. //----------------------------------------------------------------------------------------
  1506. #pragma segment TERes
  1507.  
  1508. TTETypingCommand* TTEView::DoMakeTypingCommand(const CStr2& ch)
  1509. {
  1510.     TTETypingCommand * aTypingCommand = new TTETypingCommand;
  1511.  
  1512.     aTypingCommand->ITETypingCommand(this, ch);
  1513.     return aTypingCommand;
  1514. }
  1515.  
  1516. //----------------------------------------------------------------------------------------
  1517. // TTEView::DoMenuCommand: 
  1518. //----------------------------------------------------------------------------------------
  1519. #pragma segment TESelCommand
  1520.  
  1521. void TTEView::DoMenuCommand(CommandNumber aCommandNumber)// override 
  1522. {
  1523.     switch (aCommandNumber)
  1524.     {
  1525.         case cCut:
  1526.         case cCopy:
  1527.         case cClear:
  1528.             {
  1529.                 fUpDown = FALSE;
  1530.                 PostCommand(DoMakeEditCommand(aCommandNumber));
  1531.                 break;
  1532.             }
  1533.  
  1534.         case cPaste:
  1535.             {
  1536.                 long nChars;
  1537.                 ResType dataType = '%%%%';
  1538.  
  1539.                 nChars = gClipboardMgr->GetDataToPaste(NULL, dataType);
  1540.                 if (dataType == 'TEXT')
  1541.                 {
  1542.                     if (nChars < 0)
  1543.                     {
  1544. #if qDebug
  1545.                         ProgramBreak("Couldn't get data to paste");
  1546. #endif
  1547.  
  1548.                     }
  1549.                     else
  1550.                     {
  1551.                         if (nChars - ((*fHTE)->selEnd - (*fHTE)->selStart) > fMaxChars - GetHandleSize(fText))
  1552.                         {
  1553.                             OSErr anErr;
  1554.                             anErr = MAInteractWithUser();
  1555.                             if (anErr == noErr)
  1556.                                 StdAlert(phTooManyChars);
  1557.                             else if (anErr == errAENoUserInteraction)
  1558.                                 FailOSErr(errTooManyChars);
  1559.                             else
  1560.                                 FailOSErr(anErr);
  1561.                         }
  1562.                         else
  1563.                         {
  1564.                             fUpDown = FALSE;
  1565.                             PostCommand(DoMakeEditCommand(aCommandNumber));
  1566.                         }
  1567.                     }
  1568.                 }
  1569.                 else
  1570.                 {
  1571.                     Inherited::DoMenuCommand(aCommandNumber);
  1572.                 }
  1573.                 break;
  1574.             }
  1575.  
  1576.         case cSelectAll:
  1577.             {
  1578.                 if (Focus())
  1579.                 {
  1580.                     fUpDown = FALSE;
  1581.                     SetSelection(0, (*fHTE)->teLength, kRedraw);
  1582.                     DoneTyping();
  1583.                     fSpecsChanged = TRUE;
  1584.                     ScrollSelectionIntoView(kRedraw);
  1585.                 }
  1586.                 break;
  1587.             }
  1588.  
  1589.         default:
  1590.             {
  1591.                 Inherited::DoMenuCommand(aCommandNumber);
  1592.                 break;
  1593.             }
  1594.     }
  1595. }
  1596.  
  1597. //----------------------------------------------------------------------------------------
  1598. // TTEView::DoMouseCommand: 
  1599. //----------------------------------------------------------------------------------------
  1600. #pragma segment TERes
  1601.  
  1602. void TTEView::DoMouseCommand(VPoint& theMouse,
  1603.                              TToolboxEvent* event,
  1604.                              CPoint)            // override 
  1605. {
  1606.     if (Focus() && IsVisible())
  1607.     {
  1608.         CWhileOutlinePreferred setOP(fPreferOutline);
  1609.  
  1610.         fgCurrTEView = this;                        // So the global clickLoop routine can forward
  1611.         DoneTyping();                            // Mousedown terminates the Typing command 
  1612.         fUpDown = FALSE;                        // and resets the horizontal location for up 
  1613.         // and down arrow cursor movement
  1614.         fSpecsChanged = TRUE;
  1615.         TEClick(ViewToQDPt(theMouse), event->IsShiftKeyPressed(), fHTE);
  1616.  
  1617.         // …force a re-focus b/c the focusing in ClickLoop clips down to the destrect. 
  1618.         if (IsFocused())
  1619.             InvalidateFocus();
  1620.  
  1621. #if qDrag
  1622.         // force an update of the current sleep region and cursor
  1623.         gDispatcher->InvalidateCursorRgn();
  1624. #endif // qDrag
  1625.  
  1626.         fSelAnchor = (*fHTE)->selStart;            // Remember the new selection anchor
  1627.  
  1628.         if (fIdleFreq == kMaxIdleTime)
  1629.             SetIdleFreq(0);                        // Idle ASAP 
  1630.     }
  1631. }
  1632.  
  1633. //----------------------------------------------------------------------------------------
  1634. // TTEView::DoneTyping: 
  1635. //----------------------------------------------------------------------------------------
  1636. #pragma segment TENonRes
  1637.  
  1638. void TTEView::DoneTyping()
  1639. {
  1640.     if (fTypingCommand)
  1641.     {
  1642.         fTypingCommand->CompleteTyping();
  1643.         fTypingCommand = NULL;
  1644.     }
  1645. }
  1646.  
  1647. //----------------------------------------------------------------------------------------
  1648. // TTEView::DoSetPageOffset: 
  1649. //----------------------------------------------------------------------------------------
  1650. #pragma segment TEPrint
  1651.  
  1652. void TTEView::DoSetPageOffset(const VPoint& coord)// override 
  1653.  
  1654. {
  1655.     Inherited::DoSetPageOffset(coord);
  1656.     for (VHSelect vhs = vSel; vhs <= hSel; ++vhs)
  1657.         if (coord[vhs] == 0)
  1658.             TPrintHandler::gPageOffset[vhs] += fInset[topLeft][vhs];
  1659. }
  1660.  
  1661. //----------------------------------------------------------------------------------------
  1662. // TTEView::DoSetupMenus: 
  1663. //----------------------------------------------------------------------------------------
  1664. #pragma segment TERes
  1665.  
  1666. void TTEView::DoSetupMenus()                    // override 
  1667. {
  1668.     Boolean manyChars;
  1669.  
  1670.     Inherited::DoSetupMenus();
  1671.  
  1672.     manyChars = (*fHTE)->selStart < (*fHTE)->selEnd;
  1673.     if (!MemSpaceIsLow())
  1674.     {
  1675.         if (fAcceptsChanges)                    // One way or another, we can paste text 
  1676.             gClipboardMgr->CanPaste('TEXT');    // If styles exist, all the better 
  1677.  
  1678.         Enable(cCopy, manyChars);
  1679.     }
  1680.     Enable(cSelectAll, (*fHTE)->teLength > 0);
  1681.  
  1682.     // We enable Cut even if space is low, since it's nice to be able to rescue some of
  1683.     // the stuff you have to delete even if space is low. Note that it is possible to get
  1684.     // into the "can't do any commands" situation as a result. You should be able to close
  1685.     // and save the big document, then save the rescued text elsewhere, however.
  1686.     Enable(cCut, manyChars && fAcceptsChanges);
  1687.     Enable(cClear, manyChars && fAcceptsChanges);
  1688. }
  1689.  
  1690. //----------------------------------------------------------------------------------------
  1691. // TTEView::Draw: 
  1692. //----------------------------------------------------------------------------------------
  1693. #pragma segment TERes
  1694.  
  1695. void TTEView::Draw(const VRect& area)            // override 
  1696. {
  1697.     short oldHilite;
  1698.     short oldCaretState;
  1699.  
  1700.     CWhileOutlinePreferred setOP(fPreferOutline);
  1701.  
  1702.     Boolean wasActive = ((Boolean)((*fHTE)->active != 0));
  1703.     Boolean hideSelection = (gPrinting || gDrawingPictScrap);
  1704.  
  1705.     if (hideSelection)
  1706.     {
  1707.         // we don't TEDeactivate to draw the selection as an outline
  1708.         oldHilite = TEFeatureFlag(teFOutlineHilite, teBitClear, fHTE);
  1709.  
  1710.         // we have to remember what the caret state was, because
  1711.         // TEDeactivate is going to blast it
  1712.         oldCaretState = (*fHTE)->caretState;
  1713.  
  1714.         // …prevent selection from being drawn. 
  1715.         CTemporaryRegion tempRgn;
  1716.  
  1717.         GetClip(tempRgn);
  1718.         ClipRect(gZeroRect);
  1719.         TEDeactivate(fHTE);
  1720.         SetClip(tempRgn);
  1721.     }
  1722.  
  1723.     TEUpdate(&ViewToQDRect(area), fHTE);        // normal screen update handled by
  1724.     // TextEdit directly
  1725.  
  1726.     if (hideSelection && wasActive)
  1727.     {
  1728.         // Reactivate the TE record if we deactivated it
  1729.         if (wasActive)
  1730.         {
  1731.             CTemporaryRegion tempRgn;
  1732.  
  1733.             GetClip(tempRgn);
  1734.             ClipRect(gZeroRect);
  1735.             TEActivate(fHTE);
  1736.             SetClip(tempRgn);
  1737.         }
  1738.  
  1739.         TEFeatureFlag(teFOutlineHilite, oldHilite, fHTE);
  1740.  
  1741.         // Put the caret state back to what it was
  1742.         (*fHTE)->caretState = oldCaretState;
  1743.     }
  1744.  
  1745.     Inherited::Draw(area);
  1746. }
  1747.  
  1748. //----------------------------------------------------------------------------------------
  1749. // TTEView::ExtractStyles: 
  1750. //----------------------------------------------------------------------------------------
  1751. #pragma segment TENonRes
  1752.  
  1753. void TTEView::ExtractStyles(TEStyleHandle& theStyles,
  1754.                             STHandle& theElements)
  1755. {
  1756.     theStyles = TEGetStyleHandle(fHTE);
  1757.     theElements = (*theStyles)->styleTab;
  1758. }
  1759.  
  1760. //----------------------------------------------------------------------------------------
  1761. // TTEView::ExtractText: 
  1762. //----------------------------------------------------------------------------------------
  1763. #pragma segment TENonRes
  1764.  
  1765. Handle TTEView::ExtractText() const
  1766. {
  1767.     return fText;
  1768. }
  1769.  
  1770. //----------------------------------------------------------------------------------------
  1771. // TTEView::GetPrintExtent: 
  1772. //----------------------------------------------------------------------------------------
  1773. #pragma segment TENonRes
  1774.  
  1775. VRect TTEView::GetPrintExtent()// override 
  1776. {
  1777.     VRect printExtent(Inherited::GetPrintExtent());
  1778.  
  1779.     printExtent[topLeft] += fInset[topLeft];
  1780.     printExtent[botRight] -= fInset[botRight];
  1781.     
  1782.     return printExtent;
  1783. }
  1784.  
  1785. //----------------------------------------------------------------------------------------
  1786. // TTEView::GetSelectionString: 
  1787. //----------------------------------------------------------------------------------------
  1788. #pragma segment TERes
  1789.  
  1790. void TTEView::GetSelectionString(CStr255& selection)
  1791. {
  1792.     selection.Empty();
  1793.     Handle theChars = fText;
  1794.     if (theChars && fHTE)
  1795.     {
  1796.         short start = (*fHTE)->selStart;
  1797.         short length = (short)Min(kStr255Len, (*fHTE)->selEnd - start);//!!! long->short
  1798.         if (length > 0)
  1799.             selection.CopyFrom((void*)((*theChars) + start), length);
  1800.     }
  1801. }
  1802.  
  1803. //----------------------------------------------------------------------------------------
  1804. // TTEView::GetNumberOfChars: 
  1805. //----------------------------------------------------------------------------------------
  1806. #pragma segment TERes
  1807.  
  1808. short TTEView::GetNumberOfChars()
  1809. {
  1810.     short numOfChars = 0;
  1811.  
  1812.     if (fText)
  1813.     {
  1814.         Handle theText = fText;
  1815.         short textSize = (short)GetHandleSize(theText);
  1816.  
  1817.         for (short numOfBytes = 0; numOfBytes < textSize; ++numOfBytes)
  1818.             if (MACharacterByteType(*theText, numOfBytes, smCurrentScript) != smFirstByte)
  1819.                 ++numOfChars;
  1820.     }
  1821.  
  1822.     return numOfChars;
  1823. }
  1824.  
  1825. //----------------------------------------------------------------------------------------
  1826. // TTEView::GetCharacterOffset: 
  1827. //----------------------------------------------------------------------------------------
  1828. #pragma segment TERes
  1829.  
  1830. short TTEView::GetCharacterOffset(short fromOffset)
  1831. {
  1832.     return (MACharacterByteType(*fText, fromOffset, smCurrentScript) != smLastByte) ? fromOffset : --fromOffset;
  1833. }
  1834.  
  1835.  
  1836. //----------------------------------------------------------------------------------------
  1837. // TTEView::GetBytesInCharacter: 
  1838. //----------------------------------------------------------------------------------------
  1839. #pragma segment TERes
  1840.  
  1841. short TTEView::GetBytesInCharacter(short inOffset)
  1842. {
  1843.     // return the correct number of bytes even if the offset points into the middle
  1844.     // of a two byte character
  1845.     return (MACharacterByteType(*fText, inOffset, smCurrentScript) == smSingleByte) ? 1 : 2;
  1846. }
  1847.  
  1848.  
  1849. //----------------------------------------------------------------------------------------
  1850. // TTEView::GetNextCharacterOffset: 
  1851. //----------------------------------------------------------------------------------------
  1852. #pragma segment TERes
  1853.  
  1854. short TTEView::GetNextCharacterOffset(short fromOffset)
  1855. {
  1856.     short correctedCharacterOffset = GetCharacterOffset(fromOffset);
  1857.     
  1858.     return Min (correctedCharacterOffset + GetBytesInCharacter(correctedCharacterOffset), (*fHTE)->teLength);
  1859. }
  1860.  
  1861.  
  1862. //----------------------------------------------------------------------------------------
  1863. // TTEView::GetPrevCharacterOffset: 
  1864. //----------------------------------------------------------------------------------------
  1865. #pragma segment TERes
  1866.  
  1867. short TTEView::GetPrevCharacterOffset(short fromOffset)
  1868. {
  1869.     short correctedCharacterOffset = GetCharacterOffset(fromOffset);
  1870.     
  1871.     return Max (correctedCharacterOffset - GetBytesInCharacter(correctedCharacterOffset), 0);
  1872. }
  1873.  
  1874.  
  1875. //----------------------------------------------------------------------------------------
  1876. // TTEView::GivePasteData: 
  1877. //----------------------------------------------------------------------------------------
  1878. #pragma segment TEClipboard
  1879.  
  1880. long TTEView::GivePasteData(Handle aDataHandle,
  1881.                             ResType dataType)    // override 
  1882. {
  1883.     short oldStart;
  1884.     short oldEnd;
  1885.     long aSize = 0;
  1886.     MAVolatileInit(Handle, aHandle, NULL);
  1887.     OSErr err;
  1888.     Boolean savedPerm = FALSE;
  1889.     SignedByte savedState;
  1890.  
  1891.     FailInfo fi;
  1892.     Try(fi)
  1893.     {
  1894.         if (dataType == 'TEXT')
  1895.         {
  1896.             aSize = GetHandleSize(fText);
  1897.             if (aDataHandle)
  1898.             {
  1899.                 SetPermHandleSize(aDataHandle, aSize);// Don't forget. This can fail 
  1900.                 MABlockMove((*fText), (*aDataHandle), aSize);
  1901.             }
  1902.         }
  1903.         else if (dataType == 'styl')
  1904.         {
  1905.             if (fStyleType == kWithStyle)
  1906.                 if (!SpaceForStyles(0, SHRT_MAX))
  1907.                     Failure(noErr, 0);            // We'll accept this error in worst case 
  1908.             else
  1909.             {
  1910.                 oldStart = (*fHTE)->selStart;
  1911.                 oldEnd = (*fHTE)->selEnd;
  1912.                 SetSelect(0, SHRT_MAX, fHTE);
  1913.                 aHandle = (Handle)TEGetStyleScrapHandle(fHTE);
  1914.                 SetSelect(oldStart, oldEnd, fHTE);
  1915.  
  1916.                 if (aHandle)
  1917.                 {
  1918.                     aSize = GetHandleSize(aHandle);
  1919.                     if (aDataHandle)
  1920.                     {
  1921.                         savedPerm = PermAllocation(TRUE);
  1922.                         // Try to prevent fragmentation, in case can't move while we're copying it! 
  1923.                         savedState = LockHandleHigh(aHandle);
  1924.                         // Copy styles into user-supplied handle 
  1925.                         err = PtrToXHand((*aHandle), aDataHandle, aSize);
  1926.                         HSetState(aHandle, savedState);// Okay for it to move again 
  1927.                         savedPerm = PermAllocation(savedPerm);
  1928.                         if (err != noErr)        // Maybe enough for one copy, but not two! 
  1929.                             Failure(phStylesTooBig, phStylesTooBig + messageAlert);
  1930.                     }
  1931.                     aHandle = DisposeIfHandle(aHandle);
  1932.                 }
  1933.                 else if (aDataHandle)            // Hmm. There _was_ enough memory, but the 
  1934.                     Failure(phStylesTooBig, phStylesTooBig + messageAlert);// heap is
  1935.                 // probably
  1936.                 // pretty
  1937.                 // fragmented
  1938.  
  1939.             }
  1940.         }
  1941.         else
  1942.             Failure(noTypeErr, 0);
  1943.  
  1944.         FailSpaceIsLow();
  1945.         fi.Success();
  1946.     }
  1947.     else                                        // Recover
  1948.     {
  1949.         aHandle = DisposeIfHandle(aHandle);
  1950.         fi.ReSignal();
  1951.     }
  1952.  
  1953.     return aSize;
  1954. }
  1955.  
  1956.  
  1957. //----------------------------------------------------------------------------------------
  1958. // TTEView::MakeTERecord: 
  1959. //----------------------------------------------------------------------------------------
  1960. #pragma segment TEOpen
  1961.  
  1962. void TTEView::MakeTERecord()
  1963. {
  1964.     TEHandle anHTE;
  1965.     GrafPtr oldPort;
  1966.     TextStyle aTextStyle;
  1967.  
  1968.     GetPort(&oldPort);
  1969.     SetPortWindowPort(gWorkPort);
  1970.     aTextStyle = fTextStyle;
  1971.     SetPortTextStyle(aTextStyle);
  1972.  
  1973.     VRect itsExtent(GetExtent());
  1974.     itsExtent[topLeft] += fInset[topLeft];
  1975.     itsExtent[botRight] -= fInset[botRight];
  1976.  
  1977.     CRect dest(ViewToQDRect(itsExtent));
  1978.  
  1979.     if (fStyleType == kWithStyle)
  1980.         anHTE = TEStyleNew(dest, &dest);        // Open a styled record if requested 
  1981.     else
  1982.         anHTE = TENew(&dest, &dest);            // …otherwise, do it the old way 
  1983.  
  1984.     SetPort(oldPort);
  1985.  
  1986.     FailNIL(anHTE);                                // Make sure we actually created one 
  1987.     fHTE = anHTE;                                // We did, so save off TE handle 
  1988.  
  1989.     if (fStyleType == kWithStyle)
  1990.     {
  1991.         TEStyleHandle styleHandle = TEGetStyleHandle(fHTE);
  1992.         (*styleHandle)->teRefCon = (long)this;    // set the refcon to this view
  1993.     }
  1994.  
  1995.     fgDefClickLoopProc = (*anHTE)->clickLoop;    // Just in case we want to restore it… 
  1996.     // Note that the system call SetClickLoop 
  1997.     // _cannot_ be used to set the clickProc of 
  1998.     // the TERecord. This is because the default 
  1999.     // clickproc does not follow the Pascal Parameter 
  2000.     // passing conventions that this procedure expects. 
  2001.  
  2002.     SetJustification(fJustification, kDontRedraw);// Set justification to requested value 
  2003.     ChangeWrap(fAutoWrap, FALSE);                // Install auto wrap (or CR only) 
  2004.     FailNoReserve();                            // Got to have some reserve tank 
  2005.  
  2006.     BeInPort(GetGrafPort());                    // Associate with real port 
  2007. }
  2008.  
  2009. //----------------------------------------------------------------------------------------
  2010. // TTEView::OffsetToLine: 
  2011. //----------------------------------------------------------------------------------------
  2012. #pragma segment TERes
  2013.  
  2014. short TTEView::OffsetToLine(short offset)
  2015. {
  2016.     TERec & theTERec = **fHTE;
  2017.  
  2018.     if (theTERec.nLines <= 1)
  2019.         return 0;
  2020.     else
  2021.     {
  2022.         short i;
  2023.         for (i = 0; i < theTERec.nLines; i++)
  2024.             if (theTERec.lineStarts[i] >= offset)
  2025.                 break;
  2026.  
  2027.         return i;
  2028.     }
  2029. }
  2030.  
  2031. //----------------------------------------------------------------------------------------
  2032. // TTEView::OffsetToLineStart: 
  2033. //----------------------------------------------------------------------------------------
  2034. #pragma segment TERes
  2035.  
  2036. short TTEView::OffsetToLineStart(short offset)
  2037. {
  2038.     short returnVal = 0;
  2039.     
  2040.     if ((*fHTE)->nLines > 1)
  2041.     {
  2042.         short i = OffsetToLine(offset);
  2043.         returnVal = (*fHTE)->lineStarts[i];
  2044.     }
  2045.  
  2046.     return returnVal;
  2047. }
  2048.  
  2049. //----------------------------------------------------------------------------------------
  2050. // TTEView::OffsetToLineEnd: 
  2051. //----------------------------------------------------------------------------------------
  2052. #pragma segment TERes
  2053.  
  2054. short TTEView::OffsetToLineEnd(short offset)
  2055. {
  2056.     TERec & theTERec = **fHTE;
  2057.     short returnVal = theTERec.teLength;
  2058.  
  2059.     if (theTERec.nLines > 1)
  2060.     {
  2061.         short i;
  2062.         for (i = 0; i < theTERec.nLines; i++)
  2063.         {
  2064.             if (theTERec.lineStarts[i] >= offset)
  2065.                 break;
  2066.         }
  2067.  
  2068.         if (i < theTERec.nLines - 1)
  2069.             returnVal = (theTERec.lineStarts[i + 1] - 1);
  2070.     }
  2071.  
  2072.     return returnVal;
  2073. }
  2074.  
  2075. //----------------------------------------------------------------------------------------
  2076. // TTEView::OffsetToPt: 
  2077. //----------------------------------------------------------------------------------------
  2078. #pragma segment TERes
  2079.  
  2080. VPoint TTEView::OffsetToPt(short offset)
  2081. {
  2082.     short height;
  2083.     TextStyle theStyle;
  2084.     short ascent;
  2085.  
  2086.     TEGetStyle(offset, &theStyle, &height, &ascent, fHTE);
  2087.  
  2088.     // Through System 6.0.4 TEGetPoint returns bogus numbers when the character count is 0.
  2089.     CPoint thePoint;
  2090.     if ((*fHTE)->teLength <= 0)
  2091.     {
  2092.         thePoint = fInset[topLeft].ToPoint();
  2093.         thePoint.v += ascent;
  2094.     }
  2095.     else
  2096.     {
  2097.         thePoint = TEGetPoint(offset, fHTE);
  2098.         if ((!TEIsFrontOfLine(offset, fHTE)) || ((*((*fHTE)->hText))[offset - 1] != chReturn))
  2099.             thePoint.v += ascent - height;
  2100.     }
  2101.  
  2102.     return QDToViewPt(thePoint);
  2103. }
  2104.  
  2105. //----------------------------------------------------------------------------------------
  2106. // TTEView::PtToOffset: 
  2107. //----------------------------------------------------------------------------------------
  2108. #pragma segment TERes
  2109.  
  2110. short TTEView::PtToOffset(const VPoint& aPoint)
  2111. {
  2112.     CPoint aQDPoint;
  2113.     short offset;
  2114.  
  2115.     aQDPoint = ViewToQDPt(aPoint);
  2116.     offset = TEGetOffset(aQDPoint, fHTE);
  2117.  
  2118.     if ((TEIsFrontOfLine(offset, fHTE)) && (offset) && ((*((*fHTE)->hText))[offset - 1] == chReturn) && (TEGetPoint(offset - 1, fHTE).h < aQDPoint.h))
  2119.     {
  2120.         offset--;
  2121.     }
  2122.  
  2123.     return offset;
  2124. }
  2125.  
  2126. //----------------------------------------------------------------------------------------
  2127. // TTEView::RecalcText: 
  2128. //----------------------------------------------------------------------------------------
  2129. #pragma segment TERes
  2130.  
  2131. void TTEView::RecalcText()
  2132. {
  2133.     fUpDown = FALSE;
  2134.     TECalText(fHTE);
  2135. }
  2136.  
  2137. //----------------------------------------------------------------------------------------
  2138. // TTEView::ResignedWindowTarget: 
  2139. //----------------------------------------------------------------------------------------
  2140. #pragma segment TENonRes
  2141.  
  2142. void TTEView::ResignedWindowTarget()            // override 
  2143. {
  2144.     DoHighlightSelection(fActiveHL, hlDim);
  2145.     fActiveHL = hlDim;
  2146.  
  2147.     Inherited::ResignedWindowTarget();
  2148. }
  2149.  
  2150. //----------------------------------------------------------------------------------------
  2151. // TTEView::ResignedTarget: 
  2152. //----------------------------------------------------------------------------------------
  2153. #pragma segment TENonRes
  2154.  
  2155. void TTEView::ResignedTarget()                    // override 
  2156. {
  2157.     SetActive(FALSE);
  2158.  
  2159.     Inherited::ResignedTarget();
  2160. }
  2161.  
  2162. //----------------------------------------------------------------------------------------
  2163. // TTEView::InvalidateFrameDifference: 
  2164. //----------------------------------------------------------------------------------------
  2165. #pragma segment TENonRes
  2166.  
  2167. void TTEView::InvalidateFrameDifference(const VRect& oldFrame,
  2168.                                         const VRect& newFrame)
  2169. {
  2170.     // Account for the inset
  2171.  
  2172.     VRect theOldFrame(oldFrame[topLeft] + fInset[topLeft], oldFrame[botRight] - fInset[botRight]);
  2173.     VRect theNewFrame(newFrame[topLeft] + fInset[topLeft], newFrame[botRight] - fInset[botRight]);
  2174.  
  2175.     Inherited::InvalidateFrameDifference(theOldFrame, theNewFrame);
  2176. }
  2177.  
  2178. //----------------------------------------------------------------------------------------
  2179. // TTEView::SetFrame: 
  2180. //----------------------------------------------------------------------------------------
  2181. #pragma segment TENonRes
  2182.  
  2183. void TTEView::SetFrame(const VRect& newFrame,
  2184.                        Boolean invalidate)        // override 
  2185. {
  2186.     VPoint oldSize(fSize);
  2187.  
  2188.     Inherited::SetFrame(newFrame, invalidate);
  2189.  
  2190.     if (fHTE && fSize != oldSize)
  2191.     {
  2192.         CRect itsQDExtent(GetQDExtent());
  2193.  
  2194.         CRect r(itsQDExtent[topLeft] + (fInset[topLeft].ToPoint()), (itsQDExtent[botRight] - (fInset[botRight]).ToPoint()));
  2195.  
  2196.         Boolean needCalText = (fSize.h != oldSize.h) || (r.right != (*fHTE)->destRect.right);
  2197.  
  2198.         StuffTERects(r);
  2199.         if (needCalText)
  2200.         {
  2201.             RecalcText();
  2202.             SynchView(kDontRedraw);
  2203.             short actualJust = GetActualJustification(fJustification);
  2204.             if (invalidate && ((fAutoWrap && (fSize != oldSize)) || ((actualJust == teFlushRight) || (actualJust == teCenter))))
  2205.                 ForceRedraw();
  2206.         }
  2207.     }
  2208. }
  2209.  
  2210. //----------------------------------------------------------------------------------------
  2211. // TTEView::UpdateCoordinates: 
  2212. //----------------------------------------------------------------------------------------
  2213. #pragma segment TERes
  2214.  
  2215. void TTEView::UpdateCoordinates()                // override 
  2216. {
  2217.     CPoint oldQDOrigin(fQDOrigin);
  2218.     VPoint oldViewToQDOffset(fViewToQDOffset);
  2219.  
  2220.     Inherited::UpdateCoordinates();
  2221.  
  2222.     if (fQDOrigin != oldQDOrigin || fViewToQDOffset != oldViewToQDOffset)
  2223.         if (fHTE)
  2224.         {
  2225.             CRect itsQDExtent(GetQDExtent());
  2226.  
  2227.             StuffTERects(CRect(itsQDExtent[topLeft] + (fInset[topLeft].ToPoint()), (itsQDExtent[botRight] - (fInset[botRight]).ToPoint())));
  2228.         }
  2229. }
  2230.  
  2231. //----------------------------------------------------------------------------------------
  2232. // TTEView::ScrollSelectionIntoView: 
  2233. //----------------------------------------------------------------------------------------
  2234. #pragma segment TERes
  2235.  
  2236. void TTEView::ScrollSelectionIntoView(Boolean redraw)// Override
  2237. {
  2238.     if ((GetScroller(kAnySuperView) != NULL) && Focus())// Can't scroll selection if we don't have 
  2239.     {
  2240.         // … a scroller! 
  2241.         if (fIdleFreq == kMaxIdleTime)
  2242.             SetIdleFreq(0);                        // Idle ASAP 
  2243.  
  2244.         VRect selectionRect;
  2245.         CalcSelLoc(selectionRect);
  2246.  
  2247. #if qDebugMsg
  2248.         if (gIntenseDebugging)
  2249.         {
  2250.             fprintf(stderr, "Visible CRect was: %s", (const char*)GetVisibleRect());
  2251.             fprintf(stderr, "; Sel CRect was: %s\n", (const char*)selectionRect);
  2252.         }
  2253. #endif
  2254.  
  2255.         if (!GetVisibleRect().Contains(selectionRect))
  2256.         {
  2257.             // Scroll the selection into view. accounting for the user's preference for
  2258.             // how much to jump at a time with fMinAhead. */
  2259.             VPoint minToSee(Min(fMinAhead, fSize.h - selectionRect.left), selectionRect.GetLength(vSel));
  2260. #if qDebug
  2261.             if (gIntenseDebugging)
  2262.             {
  2263.                 fprintf(stderr, "RevealRect: r = %s", (const char*)selectionRect);
  2264.                 fprintf(stderr, ", minToSee = %s\n", (const char*)minToSee);
  2265.             }
  2266. #endif
  2267.  
  2268.             RevealRect(selectionRect, minToSee, redraw);
  2269.             Focus();                            // Refocus in newly-scrolled position.
  2270.         }
  2271.     }
  2272.     else if (!fAutoWrap && fHTE)
  2273.         TESelView(fHTE);
  2274. }
  2275.  
  2276. //----------------------------------------------------------------------------------------
  2277. // TTEView::SetJustification: 
  2278. //----------------------------------------------------------------------------------------
  2279. #pragma segment TENonRes
  2280.  
  2281. void TTEView::SetJustification(short newJust,
  2282.                                Boolean redraw)
  2283. {
  2284.     TESetAlignment(newJust, fHTE);
  2285.     fJustification = newJust;
  2286.  
  2287.     CRect itsQDExtent(GetQDExtent());
  2288.  
  2289.     StuffTERects(CRect(itsQDExtent[topLeft] + (fInset[topLeft].ToPoint()), (itsQDExtent[botRight] - (fInset[botRight]).ToPoint())));
  2290.  
  2291.     if (redraw)
  2292.         ForceRedraw();
  2293. }
  2294.  
  2295. //----------------------------------------------------------------------------------------
  2296. // TTEView::SetOneStyle: 
  2297. //----------------------------------------------------------------------------------------
  2298. #pragma segment TENonRes
  2299.  
  2300. void TTEView::SetOneStyle(short theStart,
  2301.                           short theEnd,
  2302.                           short theMode,
  2303.                           const TextStyle& theStyle,
  2304.                           Boolean redraw)
  2305. {
  2306.     short saveStart;
  2307.     short saveEnd;
  2308.     FontInfo fInfo;
  2309.     TextStyle newStyle;
  2310.     short theFontHeight;
  2311.  
  2312.     CWhileOutlinePreferred setOP(fPreferOutline);
  2313.  
  2314.     InvalidateFocus();
  2315.     Focus();
  2316.     if (fStyleType == kWithStyle)
  2317.     {
  2318.         saveStart = (*fHTE)->selStart;
  2319.         saveEnd = (*fHTE)->selEnd;
  2320.         SetSelect(theStart, theEnd, fHTE);
  2321.         TESetStyle(theMode, &theStyle, redraw, fHTE);
  2322.         SetSelect(saveStart, saveEnd, fHTE);
  2323.     }
  2324.     else
  2325.     {
  2326.         if (theMode == doAll)
  2327.             newStyle = theStyle;
  2328.         else
  2329.         {
  2330.             newStyle = fTextStyle;
  2331.             if (theMode & doFont)
  2332.             {
  2333.                 newStyle.tsFont = theStyle.tsFont;
  2334.  
  2335.                 KeyScript(FontToScript(newStyle.tsFont));// …keybd input system to match new font 
  2336.             }
  2337.             if (theMode & doFace)
  2338.                 newStyle.tsFace = theStyle.tsFace;
  2339.             if (theMode & doColor)
  2340.                 newStyle.tsColor = theStyle.tsColor;
  2341.             if (theMode & addSize)
  2342.                 newStyle.tsSize += theStyle.tsSize;
  2343.             else if (theMode & doSize)
  2344.                 newStyle.tsSize = theStyle.tsSize;
  2345.         }
  2346.  
  2347.         GetTextStyleFontInfo(newStyle, fInfo, theFontHeight);// Need to get font's
  2348.         // height and ascent.
  2349.  
  2350.         {
  2351.             TERec & theTERec = **fHTE;
  2352.  
  2353.             theTERec.txSize = newStyle.tsSize;
  2354.             theTERec.txFont = newStyle.tsFont;
  2355.             theTERec.txFace = newStyle.tsFace;
  2356.             theTERec.fontAscent = fInfo.ascent;
  2357.             theTERec.lineHeight = theFontHeight;
  2358.         }
  2359.         SetIfColor(newStyle.tsColor);
  2360.  
  2361.         fTextStyle = newStyle;
  2362.     }
  2363.  
  2364.     RecalcText();
  2365.     SynchView(redraw && (fStyleType == kWithStyle));
  2366.     if (redraw && (fStyleType == kWithoutStyle))
  2367.         ForceRedraw();
  2368.  
  2369.     fSpecsChanged = TRUE;
  2370. }
  2371.  
  2372. //----------------------------------------------------------------------------------------
  2373. // TTEView::SetText: 
  2374. //----------------------------------------------------------------------------------------
  2375. #pragma segment TENonRes
  2376.  
  2377. void TTEView::SetText(const CStr255& theText)
  2378. {
  2379.     Handle theTextHandle;
  2380.  
  2381.     if (fHTE)                                    // If we're replacing text, styles are kaput
  2382.     {
  2383.         CStr255 localText(theText);
  2384.         OSErr err;
  2385.  
  2386.         Boolean allocationState = PermAllocation(TRUE);
  2387.         err = PtrToHand((Ptr) & localText[1], &theTextHandle, theText.Length());
  2388.         PermAllocation(allocationState);
  2389.  
  2390.         FailOSErr(err);
  2391.  
  2392.         StuffText(theTextHandle);
  2393.  
  2394.         // Set the insertion point to the end of the text.
  2395.         // (This is consistant with the TextEdit SetText routine)        
  2396.         long textLength = GetHandleSize(theTextHandle);
  2397.         SetSelection((short)textLength, (short)textLength, kDontRedraw);
  2398.     }
  2399. }
  2400.  
  2401. //----------------------------------------------------------------------------------------
  2402. // TTEView::ShowReverted: 
  2403. //----------------------------------------------------------------------------------------
  2404. #pragma segment TENonRes
  2405.  
  2406. void TTEView::ShowReverted()                    // override 
  2407. {
  2408.     RecalcText();
  2409.     fLastHeight = 0;
  2410.     fLastWidth = 0;
  2411.     Inherited::ShowReverted();
  2412. }
  2413.  
  2414. //----------------------------------------------------------------------------------------
  2415. // TTEView::SpaceForStyles: 
  2416. //----------------------------------------------------------------------------------------
  2417. #pragma segment TENonRes
  2418.  
  2419. Boolean TTEView::SpaceForStyles(long rangeStart,
  2420.                                 long rangeEnd)
  2421. {
  2422.     FailInfo fi;
  2423.     Try(fi)
  2424.     {
  2425.         Handle h = NewPermHandle(TENumStyles(rangeStart, rangeEnd, fHTE) * sizeof(ScrpSTElement) + 2);
  2426.  
  2427.         h = DisposeIfHandle(h);                    // Release memory back to the system 
  2428.         fi.Success();
  2429.         return TRUE;
  2430.     }
  2431.     else                                        // Recover
  2432.     {
  2433.         StdAlert(phStylesTooBig);
  2434.         // Don't resignal in this case
  2435.     }
  2436.  
  2437.     return FALSE;
  2438. }
  2439.  
  2440. //----------------------------------------------------------------------------------------
  2441. // TTEView::StuffStyles: 
  2442. //----------------------------------------------------------------------------------------
  2443. #pragma segment TENonRes
  2444.  
  2445. void TTEView::StuffStyles(TEStyleHandle theStyles,
  2446.                           STHandle theElements)
  2447. {
  2448.     if ((fStyleType == kWithStyle) && fHTE)
  2449.     {
  2450.         LHHandle oldLineHeights;
  2451.         NullStHandle theNullStyles;
  2452.         StScrpHandle theScrpHandle;
  2453.         long savedRefCon;
  2454.  
  2455.         {
  2456.             TEStyleHandle oldStyles = TEGetStyleHandle(fHTE);
  2457.             TEStyleRec & theTEStyleRec = **oldStyles;
  2458.  
  2459.             STHandle oldElements = theTEStyleRec.styleTab;
  2460.             oldLineHeights = theTEStyleRec.lhTab;
  2461.             theNullStyles = theTEStyleRec.nullStyle;
  2462.             theScrpHandle = (*theTEStyleRec.nullStyle)->nullScrap;
  2463.             savedRefCon = theTEStyleRec.teRefCon;
  2464.             oldElements = (STHandle)DisposeIfHandle((Handle)oldElements);
  2465.         }
  2466.  
  2467.         {
  2468.             TEStyleRec & theTEStyleRec = **theStyles;
  2469.  
  2470.             theTEStyleRec.styleTab = theElements;// Replace STElements handle 
  2471.             theTEStyleRec.lhTab = oldLineHeights;// Replace line heights table handle 
  2472.             theTEStyleRec.nullStyle = theNullStyles;// Replace NULL style handle 
  2473.             (*theTEStyleRec.nullStyle)->nullScrap = theScrpHandle;
  2474.             theTEStyleRec.teRefCon = savedRefCon;// restore the refcon reference 
  2475.         }
  2476.  
  2477.         // NOTE!! TESetStyleHandle will dispose of oldStyles for us! 
  2478.         TESetStyleHandle(theStyles, fHTE);
  2479.  
  2480.         RecalcText();
  2481.     }
  2482. }
  2483.  
  2484. //----------------------------------------------------------------------------------------
  2485. // TTEView::StuffText: 
  2486. //----------------------------------------------------------------------------------------
  2487. #pragma segment TENonRes
  2488.  
  2489. void TTEView::StuffText(Handle theText)
  2490. {
  2491.     if (fHTE)                                    // If we're replacing text, styles are kaput
  2492.     {
  2493.         long textLength = GetHandleSize(theText);// Check size of new text 
  2494.  
  2495.         // Remember where the selection range was & try to keep it
  2496.         // in the same state when the new text is added.  Usually, the
  2497.         // selection range should be in one of three states:  at the
  2498.         // beginning of the text, at the end of the text, or covering
  2499.         // all of the text (everything selected).  This isn't enforced,
  2500.         // though.
  2501.  
  2502.         short oldStart = (*fHTE)->selStart;
  2503.         short oldEnd = (*fHTE)->selEnd;
  2504.         if ((oldStart >= textLength) || (oldStart >= (*fHTE)->teLength))
  2505.             oldStart = (short)textLength;
  2506.         if ((oldEnd >= textLength) || (oldEnd >= (*fHTE)->teLength))
  2507.             oldEnd = (short)textLength;
  2508.  
  2509.         if (textLength > fMaxChars)
  2510.         {
  2511. #if qDebug
  2512.             ProgramBreak("Text size exceeds maximum for this view");
  2513. #endif
  2514.  
  2515.             Failure(minErr, 0);
  2516.         }
  2517.  
  2518.         // Set the selection range to cover the entire text,
  2519.         // then call TESetStyle to fix up the style table.
  2520.         // It is _very important_ to reduce the number of style runs
  2521.         // down to one _before_ changing (*fHTE)->hText because
  2522.         // TESetStyle is not smart enough to fix up the style
  2523.         // run table if its length differs from (*fHTE)->teLength.
  2524.  
  2525.         if (fStyleType == kWithStyle)
  2526.         {
  2527.             SetSelect(0, SHRT_MAX, fHTE);
  2528.             TextStyle aTextStyle = fTextStyle;
  2529.             TESetStyle(doAll, &aTextStyle, FALSE, fHTE);
  2530.         }
  2531.  
  2532.         if ((fSavedTEHandle != theText) && ((*fHTE)->hText != theText))
  2533.         {
  2534.             fSavedTEHandle = DisposeIfHandle(fSavedTEHandle);// …we have no choice but to dispose it
  2535.             fSavedTEHandle = (*fHTE)->hText;    // Save existing handle 
  2536.             (*fHTE)->hText = theText;            // Install new handle 
  2537.         }
  2538.  
  2539.         fText = theText;                        // Make a local copy, too 
  2540.         (*fHTE)->teLength = (short)textLength;    // Tell TE how long we are  //!!! long->short
  2541.  
  2542.         if (fStyleType == kWithStyle)
  2543.         {
  2544.             // At this point we are back to one plain-text
  2545.             // style, but TECalText is not smart enough to change
  2546.             // the total length of the style run table, so we
  2547.             // must do it manually here.
  2548.  
  2549.             TEStyleHandle styles = TEGetStyleHandle(fHTE);
  2550.             TEStyleRec & aTEStyleRec = **styles;
  2551.  
  2552.             // This next line sets the "dummy record" at the end of the table. See IM V-261.
  2553.             aTEStyleRec.runs[1].startChar = (*fHTE)->teLength + 1;
  2554.         }
  2555.  
  2556.         RecalcText();                            // Recalculate the line breaks and line-height tables
  2557.         SetSelect(oldStart, oldEnd, fHTE);        // Restore the old selection
  2558.     }
  2559. }
  2560.  
  2561. //----------------------------------------------------------------------------------------
  2562. // TTEView::StuffTERects: 
  2563. //----------------------------------------------------------------------------------------
  2564. #pragma segment TENonRes
  2565.  
  2566. void TTEView::StuffTERects(const CRect& newTERect)
  2567. {
  2568.     CWhileOutlinePreferred setOP(fPreferOutline);
  2569.  
  2570.     TextStyle aTextStyle = fTextStyle;
  2571.  
  2572.     FontInfo aFontInfo;
  2573.     short theFontHeight;
  2574.     GetTextStyleFontInfo(aTextStyle, aFontInfo, theFontHeight);
  2575.  
  2576.     CRect localRect(newTERect);
  2577.     short actualJust = GetActualJustification(fJustification);
  2578.     if ((fSizeDeterminer[hSel] == sizeVariable) && (actualJust != teJustCenter) && !fStyleType && !fAutoWrap)
  2579.     {
  2580.         if ((actualJust == teJustLeft) || (actualJust == teForceLeft))
  2581.             localRect.right = localRect.right + aFontInfo.widMax;
  2582.         else
  2583.             localRect.left = localRect.left - aFontInfo.widMax;
  2584.     }
  2585.     else
  2586.         localRect.right = (short)Max(localRect.right, localRect.left + aFontInfo.widMax);//!!! long->short
  2587.  
  2588.     (*fHTE)->destRect = localRect;
  2589.     (*fHTE)->viewRect = localRect;
  2590. }
  2591.  
  2592. //----------------------------------------------------------------------------------------
  2593. // TTEView::SynchView: 
  2594. //----------------------------------------------------------------------------------------
  2595. #pragma segment TERes
  2596.  
  2597. void TTEView::SynchView(Boolean redraw)
  2598.  
  2599. {
  2600.     const short kInsertionBarWidth = 1;            // insertion bar is one pixel wide
  2601.  
  2602.     long theHeight = CalcRealHeight();
  2603.  
  2604.     long theWidth;
  2605.     Boolean doRealWidth = (fSizeDeterminer[hSel] == sizeVariable) && !fStyleType && !fAutoWrap;
  2606.     if (doRealWidth)
  2607.         theWidth = CalcRealWidth() + kInsertionBarWidth * 2;
  2608.  
  2609.     if ((fLastHeight != theHeight) || (doRealWidth && (fLastWidth != theWidth)))
  2610.     {
  2611.         if (doRealWidth)
  2612.             fLastWidth = theWidth;                // Width is expensive to calculate. Cache
  2613.         // for CalcMinFrame
  2614.  
  2615.         AdjustFrame();                            // may need to grow view 
  2616.         fLastHeight = theHeight;                // Remember new height value 
  2617.     }
  2618.  
  2619.     // First, make sure selection is visible (this conveniently focuses). Then, repair any
  2620.     // extra feedback which TextEdit may have mashed.
  2621.     if (redraw && Focus())
  2622.     {
  2623.         ScrollSelectionIntoView(redraw);
  2624.         DoHighlightSelection(hlOff, GetCurrentHL());
  2625.         if (GetPrintHandler())
  2626.             DoDrawPrintFeedback(GetDrawableRect());
  2627.     }
  2628. }
  2629.  
  2630. //----------------------------------------------------------------------------------------
  2631. // TTEView::WriteToDeskScrap: 
  2632. //----------------------------------------------------------------------------------------
  2633. #pragma segment TENonRes
  2634.  
  2635. void TTEView::WriteToDeskScrap()                // override 
  2636. {
  2637.     FailOSErr(gClipboardMgr->PutDeskScrapData('TEXT', fText));
  2638.  
  2639.     if ((fStyleType == kWithStyle) && SpaceForStyles(0, SHRT_MAX))
  2640.     {
  2641.         short saveStart = (*fHTE)->selStart;
  2642.         short saveEnd = (*fHTE)->selEnd;
  2643.         SetSelect(0, SHRT_MAX, fHTE);
  2644.         Handle aHandle = (Handle)(TEGetStyleScrapHandle(fHTE));
  2645.         SetSelect(saveStart, saveEnd, fHTE);
  2646.         FailNIL(aHandle);
  2647.         FailOSErr(gClipboardMgr->PutDeskScrapData('styl', aHandle));
  2648.     }
  2649. }
  2650.  
  2651. //----------------------------------------------------------------------------------------
  2652. // TTEView::SetActive: 
  2653. //----------------------------------------------------------------------------------------
  2654. #pragma segment TERes
  2655. void TTEView::SetActive(Boolean state)
  2656. {
  2657.     CWhileOutlinePreferred setOP(fPreferOutline);
  2658.  
  2659.     if (fHTE && Focus())                        // Try to focus because TEActivate/TEDeactivate may draw 
  2660.         if (state)
  2661.         {
  2662.             if (fIdleFreq == kMaxIdleTime)
  2663.                 SetIdleFreq(0);                    // Idle ASAP 
  2664.             SetKeyScript(FontToScript(fTextStyle.tsFont));
  2665.             TEActivate(fHTE);
  2666.             fgCurrTEView = this;                    // So the global clickLoop routine can forward 
  2667.         }
  2668.         else
  2669.         {
  2670.             TEDeactivate(fHTE);
  2671.             DoneTyping();
  2672.             fSpecsChanged = TRUE;
  2673.         }
  2674. }
  2675.  
  2676. //----------------------------------------------------------------------------------------
  2677. // TTEView::SetEnable: 
  2678. //----------------------------------------------------------------------------------------
  2679. #pragma segment TERes
  2680.  
  2681. void TTEView::SetEnable(Boolean state)
  2682. {
  2683.     if (state && (fIdleFreq == kMaxIdleTime))
  2684.         SetIdleFreq(0);                            // Get correct idle set ASAP 
  2685.  
  2686.     Inherited::SetEnable(state);
  2687. }
  2688.  
  2689. //----------------------------------------------------------------------------------------
  2690. // TTEView::GetEditText: 
  2691. //----------------------------------------------------------------------------------------
  2692. #pragma segment TERes
  2693.  
  2694. TEditText* TTEView::GetEditText()
  2695. {
  2696.     // TDialogTEView overrides this to return fEditText. 
  2697.     return NULL;
  2698. }
  2699.  
  2700. //----------------------------------------------------------------------------------------
  2701. // TTEView::WordBounds: 
  2702. //----------------------------------------------------------------------------------------
  2703. #pragma segment TERes
  2704.  
  2705. Boolean TTEView::WordBounds(short charPos,
  2706.                             short& wordStart,
  2707.                             short& wordEnd)
  2708. {
  2709.     wordStart = charPos;
  2710.     wordEnd = charPos;
  2711.  
  2712.     if ((charPos < 0) || (charPos > (*fHTE)->teLength - 1))
  2713.         return FALSE;
  2714.  
  2715.     // Start on a character boundary
  2716.     if (MACharacterByteType((*fText), charPos, smCurrentScript) == smFirstByte)
  2717.         charPos++;
  2718.  
  2719.     OffsetTable offs;
  2720.     FindWord((*fText), (*fHTE)->teLength, charPos, TRUE, NULL, offs);
  2721.     wordStart = (short)Min(offs[0].offFirst, offs[0].offSecond - 1);//!!! long->short
  2722.     wordEnd = (short)Max(offs[0].offFirst, offs[0].offSecond - 1);//!!! long->short
  2723.  
  2724.     return ((wordStart < wordEnd) || (MACharacterType((*fText), wordStart, smCurrentScript) % 8 != smCharPunct));
  2725. }
  2726.  
  2727. #if qDrag
  2728.  
  2729. //----------------------------------------------------------------------------------------
  2730. // TTEView::DoMakeDragCursorRegion: 
  2731. //----------------------------------------------------------------------------------------
  2732. #pragma segment MADragRes
  2733.  
  2734. RgnHandle TTEView::DoMakeDragCursorRegion()
  2735. {
  2736.     RgnHandle dragCursorRegion = MakeNewRgn();
  2737.  
  2738.     if (HasDragManager())
  2739.     {
  2740.         CWhileOutlinePreferred setOP(fPreferOutline);
  2741.         TEGetHiliteRgn(dragCursorRegion, fHTE);
  2742.     }
  2743.  
  2744.     return dragCursorRegion;
  2745. }
  2746.  
  2747. //----------------------------------------------------------------------------------------
  2748. // TTEView::WillDrag: 
  2749. //----------------------------------------------------------------------------------------
  2750. #pragma segment MADragRes
  2751.  
  2752. Boolean TTEView::WillDrag(const VPoint& localMouse,
  2753.                           const RgnHandle dragCursorRegion)
  2754. {
  2755.     return (!IsShiftKeyDown() && Inherited::WillDrag(localMouse, dragCursorRegion));
  2756. }
  2757.  
  2758. //----------------------------------------------------------------------------------------
  2759. // TTEView::GetWillDragCursorID: 
  2760. //----------------------------------------------------------------------------------------
  2761. #pragma segment MADragRes
  2762.  
  2763. short TTEView::GetWillDragCursorID()
  2764. {
  2765.     return kNoResource;
  2766. }
  2767.  
  2768. //----------------------------------------------------------------------------------------
  2769. // TTEView::GetIsDraggingCursorID: 
  2770. //----------------------------------------------------------------------------------------
  2771. #pragma segment MADragNonRes
  2772.  
  2773. short TTEView::GetIsDraggingCursorID()
  2774. {
  2775.     return kNoResource;
  2776. }
  2777.  
  2778. //----------------------------------------------------------------------------------------
  2779. // TTEView::DoAddDragContent: 
  2780. //----------------------------------------------------------------------------------------
  2781. #pragma segment MADragNonRes
  2782.  
  2783. void TTEView::DoAddDragContent()
  2784. {
  2785.     TDragItem * dragItem = TDragDropSession::fgDragDropSession->AddDragItem(1);
  2786.  
  2787.     CFlavorFlags flags;
  2788.     dragItem->PromiseFlavor('TEXT', flags);
  2789.     StScrpHandle styleHandle = TEGetStyleScrapHandle(fHTE);
  2790.     if (styleHandle)
  2791.     {
  2792.         dragItem->PromiseFlavor('styl', flags);
  2793.         DisposeIfHandle((Handle)styleHandle);
  2794.     }
  2795. }
  2796.  
  2797. //----------------------------------------------------------------------------------------
  2798. // TTEView::WillAcceptDrop:
  2799. //----------------------------------------------------------------------------------------
  2800. #pragma segment MADragNonRes
  2801.  
  2802. Boolean TTEView::WillAcceptDrop(CDragItemIterator& dragItemIterator)
  2803. {
  2804.     if (TDragDropSession::fgDragDropSession->GetItemCount() != 1)
  2805.         return FALSE;
  2806.  
  2807.     TDragItem * firstItem = dragItemIterator.FirstDragItem();
  2808.     return firstItem->FlavorExists('TEXT');
  2809. }
  2810.  
  2811. //----------------------------------------------------------------------------------------
  2812. // TTEView::DoDragEnter:
  2813. //----------------------------------------------------------------------------------------
  2814. #pragma segment MADragNonRes
  2815.  
  2816. void TTEView::DoDragEnter()
  2817. {
  2818.     fLastCaretOffset = 0;
  2819.     fLastCaretTime = 0L;
  2820.     fCaretIsShown = FALSE;
  2821.  
  2822.     if (TDragDropSession::fgDragDropSession->GetCurrentDragSource() == this)
  2823.     {
  2824.         fHiliteRgn = MakeNewRgn();
  2825.         CWhileOutlinePreferred setOP(fPreferOutline);
  2826.         TEGetHiliteRgn(fHiliteRgn, fHTE);
  2827.         FailNIL(fHiliteRgn);
  2828.     }
  2829. }
  2830.  
  2831. //----------------------------------------------------------------------------------------
  2832. // TTEView::DoDragWithin:
  2833. //----------------------------------------------------------------------------------------
  2834. #pragma segment MADragNonRes
  2835.  
  2836. void TTEView::DoDragWithin(const VPoint& localMouse)
  2837. {
  2838.     unsigned long currentTime = TickCount();
  2839.     short offset = -1;
  2840.     Boolean caretMoved = TRUE;
  2841.  
  2842.     // if this view is the source and the target of the drag, don't allow dropping
  2843.     // into the selection
  2844.     if (fHiliteRgn && PtInRgn(ViewToQDPt(localMouse), fHiliteRgn))
  2845.     {
  2846.         if (fLastCaretOffset != -1)
  2847.         {
  2848.             offset = -1;
  2849.             caretMoved = TRUE;                    // force redraw
  2850.         }
  2851.     }
  2852.     else
  2853.     {
  2854.         offset = PtToOffset(localMouse);
  2855.         caretMoved = (fLastCaretOffset != offset);
  2856.     }
  2857.  
  2858.     if (caretMoved && fCaretIsShown)
  2859.         DrawCaret(fLastCaretOffset);
  2860.  
  2861.     if (caretMoved || (currentTime - fLastCaretTime) > GetCaretTime())
  2862.     {
  2863.         if (offset != -1)
  2864.             DrawCaret(offset);
  2865.         fLastCaretOffset = offset;
  2866.         fLastCaretTime = currentTime;
  2867.     }
  2868. }
  2869.  
  2870. //----------------------------------------------------------------------------------------
  2871. // TTEView::DoDragLeave:
  2872. //----------------------------------------------------------------------------------------
  2873. #pragma segment MADragNonRes
  2874.  
  2875. void TTEView::DoDragLeave()
  2876. {
  2877.     if (fCaretIsShown)
  2878.         DrawCaret(fLastCaretOffset);
  2879.  
  2880.     if (fHiliteRgn)
  2881.         fHiliteRgn = DisposeIfRgnHandle(fHiliteRgn);
  2882. }
  2883.  
  2884. //----------------------------------------------------------------------------------------
  2885. // TTEView::DoMakeDragDropCommand:
  2886. //----------------------------------------------------------------------------------------
  2887. #pragma segment MADragNonRes
  2888.  
  2889. TCommand* TTEView::DoMakeDragDropCommand(CommandNumber itsCommandNumber,
  2890.                                          CDragItemIterator& dragItemIterator)
  2891. {
  2892.     TCommand * returnCommand = NULL;
  2893.  
  2894.     switch (itsCommandNumber)
  2895.     {
  2896.         case cDrag:
  2897.             {
  2898.                 TTECommand * dragCommand = new TTECommand;
  2899.                 dragCommand->ITECommand(this, itsCommandNumber, TRUE);
  2900.                 returnCommand = dragCommand;
  2901.             }
  2902.             break;
  2903.  
  2904.         case cDrop:
  2905.             {
  2906.                 Handle textHandle = NULL;
  2907.                 StScrpHandle textStyles = NULL;
  2908.  
  2909.                 TDragItem * firstItem = dragItemIterator.FirstDragItem();
  2910.                 firstItem->FocusOnFlavor('TEXT');
  2911.                 textHandle = firstItem->GetDataAsHandle();
  2912.                 FailNIL(textHandle);
  2913.  
  2914.                 if (firstItem->FlavorExists('styl'))
  2915.                 {
  2916.                     firstItem->FocusOnFlavor('styl');
  2917.                     textStyles = (StScrpHandle)firstItem->GetDataAsHandle();
  2918.                 }
  2919.  
  2920.                 TTEDragDropCommand * dropCommand = new TTEDragDropCommand;
  2921.                 dropCommand->ITEDragDropCommand(this, itsCommandNumber);
  2922.                 dropCommand->SetNewText(textHandle, textStyles);
  2923.                 dropCommand->SetNewStart(fLastCaretOffset);
  2924.                 returnCommand = dropCommand;
  2925.             }
  2926.             break;
  2927.  
  2928.         case cDragMove:
  2929.             {
  2930.                 if (fLastCaretOffset != -1)        // can't drop into selection
  2931.                 {
  2932.                     TTEDragMoveCommand * dragMoveCommand = new TTEDragMoveCommand;
  2933.                     dragMoveCommand->ITEDragMoveCommand(this, itsCommandNumber, fLastCaretOffset);
  2934.                     returnCommand = dragMoveCommand;
  2935.                 }
  2936.             }
  2937.             break;
  2938.  
  2939.         default:
  2940.             returnCommand = Inherited::DoMakeDragDropCommand(itsCommandNumber, dragItemIterator);
  2941.             break;
  2942.     }
  2943.     return returnCommand;
  2944. }
  2945.  
  2946. //----------------------------------------------------------------------------------------
  2947. // TTEView::DoFulfillPromise
  2948. //----------------------------------------------------------------------------------------
  2949. #pragma segment MADragNonRes
  2950.  
  2951. void TTEView::DoFulfillPromise(TDragItem* promisedItem)
  2952. {
  2953.     switch (promisedItem->GetFlavorType())
  2954.     {
  2955.         case 'TEXT':
  2956.             {
  2957.                 MAVolatileInit(SignedByte, handleState, LockHandle(fText));
  2958.  
  2959.                 FailInfo fi;
  2960.                 Try(fi)
  2961.                 {
  2962.                     long byteCount = (*fHTE)->selEnd - (*fHTE)->selStart;
  2963.                     char* textPtr = (char*) * fText + (*fHTE)->selStart;
  2964.                     promisedItem->SetData(textPtr, byteCount);
  2965.                     HSetState(fText, handleState);
  2966.                     fi.Success();
  2967.                 }
  2968.                 else
  2969.                 {
  2970.                     HSetState(fText, handleState);
  2971.                     fi.error = cantGetFlavorErr;
  2972.                     fi.ReSignal();
  2973.                 }
  2974.             }
  2975.             break;
  2976.  
  2977.         case 'styl':
  2978.             {
  2979.                 MAVolatileInit(StScrpHandle, stylHandle, NULL);
  2980.  
  2981.                 FailInfo fi;
  2982.                 Try(fi)
  2983.                 {
  2984.                     stylHandle = TEGetStyleScrapHandle(fHTE);
  2985.                     FailNIL(stylHandle);
  2986.  
  2987.                     promisedItem->SetDataFromHandle((Handle)stylHandle);
  2988.                     DisposeIfHandle((Handle)stylHandle);
  2989.                     fi.Success();
  2990.                 }
  2991.                 else
  2992.                 {
  2993.                     DisposeIfHandle((Handle)stylHandle);
  2994.                     fi.error = cantGetFlavorErr;
  2995.                     fi.ReSignal();
  2996.                 }
  2997.             }
  2998.             break;
  2999.  
  3000.         default:
  3001.             Inherited::DoFulfillPromise(promisedItem);
  3002.             break;
  3003.     }
  3004. }
  3005.  
  3006. //----------------------------------------------------------------------------------------
  3007. // TTEView::DrawCaret: 
  3008. //----------------------------------------------------------------------------------------
  3009. #pragma segment MADragNonRes
  3010.  
  3011. void TTEView::DrawCaret(short offset)
  3012. {
  3013.     //    Get the coordinates and the line of the offset to draw the caret.
  3014.     CPoint theLoc(TEGetPoint(offset, fHTE));
  3015.     short theLine = TEGetLine(offset, fHTE);
  3016.  
  3017.     short lineHeight = (short)TEGetHeight(theLine, theLine, fHTE);
  3018.  
  3019.     //    For some reason, TextEdit doesn't return the proper coordinates
  3020.     //    of the last offset in the field if the last character in the record
  3021.     //    is a carriage return. TEGetPoint returns a point that is one line
  3022.     //    higher than expected. The following code fixes this problem.
  3023.  
  3024.     if ((offset == (*fHTE)->teLength) && (*((*fHTE)->hText))[(*fHTE)->teLength - 1] == 0x0D)
  3025.         theLoc.v += lineHeight;
  3026.  
  3027.     PenNormal();
  3028.     // The caret supposed to be nice and dark (which the white pattern will accomplish)
  3029.     PenPat(&qd.white);
  3030.     PenMode(notPatXor);                            //    set invert mode
  3031.  
  3032.     MoveToPt(theLoc - CPoint(1, 1));            //    Draw the caret image
  3033.     Line(0, 1 - lineHeight);
  3034.  
  3035.     PenNormal();                                // reset the pen
  3036.  
  3037.     fCaretIsShown = !fCaretIsShown;
  3038. }
  3039.  
  3040. #endif // qDrag
  3041.  
  3042. //----------------------------------------------------------------------------------------
  3043. // WriteChar: 
  3044. //----------------------------------------------------------------------------------------
  3045. #if qDebug
  3046. #pragma segment TEDebug
  3047.  
  3048. const short kMaxIndex = 2047;
  3049. typedef char x[kMaxIndex];
  3050. typedef x* XPtr;
  3051. typedef XPtr* XHandle;
  3052.  
  3053.  
  3054. void TTEView::WriteChar(short index,
  3055.                         Handle hText)
  3056. {
  3057.     if (index <= kMaxIndex)
  3058.         fprintf(stderr, "[%1d:%1d]", index, *((XHandle)hText)[index]);
  3059. }
  3060. #endif
  3061.  
  3062. //----------------------------------------------------------------------------------------
  3063. // DumpTERecord: 
  3064. //----------------------------------------------------------------------------------------
  3065. #if qDebug
  3066. #pragma segment TEDebug
  3067. void TTEView::DumpTERecord(TEHandle aTEH)
  3068. {
  3069.     const short kMaxCharsToPrint = 100;
  3070.  
  3071.     short size;
  3072.  
  3073.     fprintf(stderr, "TE -- dest CRect: %s\n", (const char*)CRect((*aTEH)->destRect));
  3074.  
  3075.     size = (*aTEH)->teLength;
  3076.     fprintf(stderr, "Line ht: %1d", (*aTEH)->lineHeight);
  3077.     fprintf(stderr, "; teLength: %1d", size);
  3078.     fprintf(stderr, "; hText length: %1d", GetHandleSize((*aTEH)->hText));
  3079.     fprintf(stderr, "; lines: %1d", (*aTEH)->nLines);
  3080.     fprintf(stderr, "\n");
  3081.  
  3082.     if (gIntenseDebugging)
  3083.     {
  3084.         Handle hText = (*aTEH)->hText;
  3085.  
  3086.         fprintf(stderr, "Chars: ");
  3087.         long minSize = Min(2047, size - 1);
  3088.         for (short i = 0; i <= Min(kMaxCharsToPrint, minSize); ++i)
  3089.         {
  3090.             WriteChar(i, hText);
  3091.             if (i % 10 == 9)
  3092.                 fprintf(stderr, "\n");
  3093.         }
  3094.         fprintf(stderr, "\n");
  3095.  
  3096.         fprintf(stderr, "InPort vis bbox: %s", (const char*)CRect((*TWindow::GetVisRegion((*aTEH)->inPort))->rgnBBox));
  3097.         fprintf(stderr, "; clip bbox: %s\n", (const char*)CRect((*TView::GetClipRegion((*aTEH)->inPort))->rgnBBox));
  3098.  
  3099.         if ((*aTEH)->inPort != qd.thePort)
  3100.         {
  3101.             fprintf(stderr, "thePort vis bbox: %s", (const char*)CRect((*TWindow::GetVisRegion(qd.thePort))->rgnBBox));
  3102.             fprintf(stderr, "; clip bbox: %s\n", (const char*)CRect((*TView::GetClipRegion(qd.thePort))->rgnBBox));
  3103.         }
  3104.     }
  3105.  
  3106. }
  3107. #endif
  3108.  
  3109. //----------------------------------------------------------------------------------------
  3110. // SetSelect:  Usually, TTEView::SetSelection should be used instead.  This
  3111. // procedure is used by MacApp to set the selection 'behind the scenes' (that is,
  3112. // in instances where an O.S. routine opperates on the current selection, but we
  3113. // want to change a piece of the text without changing the selection).
  3114. //----------------------------------------------------------------------------------------
  3115. #pragma segment TERes
  3116.  
  3117. void TTEView::SetSelect(short theStart,
  3118.                         short theEnd,
  3119.                         TEHandle hTE)
  3120. {
  3121.     theStart = (short)Max(theStart, 0);
  3122.  
  3123.     (*hTE)->selStart = theStart;
  3124.     (*hTE)->selEnd = (short)MinMax(theStart, theEnd, (*hTE)->teLength);
  3125. }
  3126.  
  3127. //----------------------------------------------------------------------------------------
  3128. // ClickLoopForTTEView: 
  3129. //----------------------------------------------------------------------------------------
  3130. #pragma segment TENonRes
  3131.  
  3132. pascal Boolean TTEView::ClickLoopForTTEView()
  3133. {
  3134.     return fgCurrTEView ? fgCurrTEView->ClickLoop() : TRUE;
  3135. }
  3136.  
  3137. //----------------------------------------------------------------------------------------
  3138. // TEGetLine: 
  3139. //----------------------------------------------------------------------------------------
  3140. #pragma segment TENonRes
  3141.  
  3142. short TTEView::TEGetLine(short offset,
  3143.                          TEHandle theTE)
  3144. //    TEGetLine, given an offset and a TextEdit handle, returns the line number
  3145. //    of the line that contains the offset.
  3146. {
  3147.     short returnVal;
  3148.  
  3149.     if (offset > (*theTE)->teLength)
  3150.         returnVal = (*theTE)->nLines;
  3151.     else
  3152.     {
  3153.         short line = 0;
  3154.         while ((*theTE)->lineStarts[line] < offset)
  3155.             line++;
  3156.  
  3157.         returnVal = line;
  3158.     }
  3159.  
  3160.     return returnVal;
  3161. }
  3162.  
  3163. //----------------------------------------------------------------------------------------
  3164. // TEIsFrontOfLine: 
  3165. //----------------------------------------------------------------------------------------
  3166. #pragma segment TENonRes
  3167.  
  3168. short TTEView::TEIsFrontOfLine(short offset,
  3169.                                TEHandle theTE)
  3170. //    TEIsFrontOfLine, given an offset and a TextEdit handle, returns true if
  3171. //    the given offset is at the beginning of a line start.
  3172. {
  3173.     short line = 0;
  3174.  
  3175.     if ((*theTE)->teLength == 0)
  3176.         return TRUE;
  3177.  
  3178.     if (offset >= (*theTE)->teLength)
  3179.         return ((*((*theTE)->hText))[(*theTE)->teLength - 1] == chReturn);
  3180.  
  3181.     while ((*theTE)->lineStarts[line] < offset)
  3182.         line++;
  3183.  
  3184.     return ((*theTE)->lineStarts[line] == offset);
  3185. }
  3186.  
  3187. //----------------------------------------------------------------------------------------
  3188. // IsBlank: 
  3189. //----------------------------------------------------------------------------------------
  3190. #pragma segment TENonRes
  3191.  
  3192. Boolean TTEView::IsBlank(Handle theText,
  3193.                          short offset,
  3194.                          short& length)
  3195. {
  3196.     Boolean returnVal = FALSE;
  3197.  
  3198.     short i = MACharacterType(*theText, offset, smCurrentScript);
  3199.     if ((i & smcClassMask) == smPunctBlank)
  3200.     {
  3201.         length = MACharacterByteType(*theText, offset, smCurrentScript) == smSingleByte ? 1 : 2;
  3202.  
  3203.         returnVal = TRUE;
  3204.     }
  3205.     else
  3206.         length = 0;
  3207.  
  3208.     return returnVal;
  3209. }
  3210.  
  3211.  
  3212. //----------------------------------------------------------------------------------------
  3213. // End of UTEView.cp
  3214.  
  3215. #pragma segment Inline
  3216.  
  3217.